如何在C ++中转换类型?

时间:2022-10-07 16:05:02

I'm using two different libraries in my project, and both of them supply a basic rectangle struct. The problem with this is that there seems to be no way to insert a conversion between the types, so I can't call a function in one library with the result from a function in the other. If I was the author of either of these, I could create conversions, from the outside, I can't.

我在我的项目中使用了两个不同的库,它们都提供了一个基本的矩形结构。这个问题是似乎没有办法在类型之间插入转换,所以我不能用一个函数调用一个库中的函数。如果我是其中任何一个的作者,我可以从外部创建转换,但我不能。

library a:

typedef struct rectangle { sint16 x; sint16 y; uint16 w; uint16 h; } rectangle;

library b:

class Rect {
  int x; int y; int width; int height;
  /* ... */
};

Now, I can't make a converter class, because C++ will only look for a conversion in one step. This is probably a good thing, because there would be a lot of possibilities involving creating new objects of all kinds of types.

现在,我无法创建转换器类,因为C ++只会在一个步骤中查找转换。这可能是一件好事,因为有很多可能涉及创建各种类型的新对象。

I can't make an operator that takes the struct from a and supplies an object of the class from b:

我不能创建一个从a获取结构的运算符,并从b提供类的对象:

foo.cpp:123 error: ‘operator b::Rect(const rectangle&)’ must be a nonstatic member function

So, is there a sensible way around this?

那么,有一个明智的方法吗?

edit:

I should perhaps also point out that I'd really like some solution that makes working with the result seamless, since I don't expect to be that coder. (Though I agree, old-school, explicit, conversion would have been a good choice. The other branch, reinterpret_cast has the same problem..)

我或许也应该指出,我真的很喜欢一些能够使结果无缝合作的解决方案,因为我不希望成为那样的编码器。 (虽然我同意,老派,明确,转换本来是一个不错的选择。另一个分支,reinterpret_cast有同样的问题..)

edit2:

Actually, none of the suggestions really answer my actual question, Konrad Rudolph seems to be correct. C++ actually can't do this. Sucks, but true. (If it makes any difference, I'm going to try subclassing as suggested by CodingTheWheel.

实际上,没有一个建议能真正回答我的实际问题,Konrad Rudolph似乎是正确的。 C ++实际上不能这样做。糟透了,但是确实如此。 (如果它有任何区别,我将按照CodingTheWheel的建议尝试子类化。

7 个解决方案

#1


2  

If you can't modify the structures then you have no alternative to writing a manual conversion function because overloading conversion operators only works within the class body. There's no other way.

如果您无法修改结构,则除了编写手动转换函数之外别无选择,因为重载转换运算符仅适用于类体。别无他法。

#2


4  

Create an intermediate shim type "RectangleEx", and define custom conversions to/from the 3rd-party string types. Whenever you speak to either API, do so through the shim class.

创建一个中间填充程序类型“RectangleEx”,并定义与第三方字符串类型之间的自定义转换。无论何时与任何API通信,都可以通过填充类进行操作。

Another way would be to derive a class from either rect or Rectangle, and insert conversions/constructors there.

另一种方法是从rect或Rectangle派生一个类,并在那里插入转换/构造函数。

#3


3  

Not sure how sensible this is, but how about something like this:

不确定这是多么明智,但是这样的事情怎么样:

class R
{
public:
    R(const rectangle& r) { ... };
    R(const Rect& r) { ... };

    operator rectangle() const { return ...; }
    operator Rect() const { return ...; }

private:
    ...
};

Then you can just wrap every rectangle in R() and the "right thing" will happen.

然后你可以将每个矩形包裹在R()中,并且“正确的事物”将会发生。

#4


0  

It may not be feasible in your case, but I've seen people employ a little preprocessor-foo to massage the types into compatibility.

在你的情况下它可能不可行,但我看到人们使用一些预处理器foo来按摩类型兼容性。

Even this assumes that you are building one or both libraries.

即使这假设您正在构建一个或两个库。

It is also possible that you don't want to do this at all, but want to re-evaulate some early decision. Or not.

您可能根本不想这样做,但想要重新评估一些早期决定。或不。

#5


0  

Why not something simple like this: (note this may/probably won't compile) but you get the idea...

为什么不是这样简单的东西:(注意这可能/可能不会编译)但你明白了......


private Rect* convert(const rectangle& src)
{
    return new Rect(src.x,src.y,src.w,src.h);
}
int main()
{
    rectangle r;
    r.x = 1;
    r.y = 2;
    r.w = 3;
    r.h = 4;

    Rect* foo = convert(&r);
    ...
    delete foo;

}

EDIT: Looks like koko's and I have the same idea.

编辑:看起来像koko和我有相同的想法。

#6


0  

If the structs were the same internally, you could do a reinterpret_cast; however, since it looks like you have 16-bit vs 32-bit fields, you're probably stuck converting on each call, or writing wrappers for all functions of one of the libraries.

如果结构在内部是相同的,你可以做一个reinterpret_cast;但是,由于看起来你有16位和32位字段,你可能在每次调用时都没有转换,或者为其中一个库的所有函数编写包装器。

#7


-1  

Maybe you could try it with operator overloading ? (Maybe a = operator which is not a method of your class) ?

也许你可以尝试运算符重载? (也许a =运算符不是你班级的方法)?

Rect operator= (const Rect&,const rectangle&)

Rect运算符=(const Rect&,const矩形&)

More about this in the C++ programming language by Bjarne Stroustrup or maybe on this page: http://www.cs.caltech.edu/courses/cs11/material/cpp/donnie/cpp-ops.html

有关Bjarne Stroustrup的C ++编程语言的更多信息,或者可能在此页面上:http://www.cs.caltech.edu/courses/cs11/material/cpp/donnie/cpp-ops.html

#1


2  

If you can't modify the structures then you have no alternative to writing a manual conversion function because overloading conversion operators only works within the class body. There's no other way.

如果您无法修改结构,则除了编写手动转换函数之外别无选择,因为重载转换运算符仅适用于类体。别无他法。

#2


4  

Create an intermediate shim type "RectangleEx", and define custom conversions to/from the 3rd-party string types. Whenever you speak to either API, do so through the shim class.

创建一个中间填充程序类型“RectangleEx”,并定义与第三方字符串类型之间的自定义转换。无论何时与任何API通信,都可以通过填充类进行操作。

Another way would be to derive a class from either rect or Rectangle, and insert conversions/constructors there.

另一种方法是从rect或Rectangle派生一个类,并在那里插入转换/构造函数。

#3


3  

Not sure how sensible this is, but how about something like this:

不确定这是多么明智,但是这样的事情怎么样:

class R
{
public:
    R(const rectangle& r) { ... };
    R(const Rect& r) { ... };

    operator rectangle() const { return ...; }
    operator Rect() const { return ...; }

private:
    ...
};

Then you can just wrap every rectangle in R() and the "right thing" will happen.

然后你可以将每个矩形包裹在R()中,并且“正确的事物”将会发生。

#4


0  

It may not be feasible in your case, but I've seen people employ a little preprocessor-foo to massage the types into compatibility.

在你的情况下它可能不可行,但我看到人们使用一些预处理器foo来按摩类型兼容性。

Even this assumes that you are building one or both libraries.

即使这假设您正在构建一个或两个库。

It is also possible that you don't want to do this at all, but want to re-evaulate some early decision. Or not.

您可能根本不想这样做,但想要重新评估一些早期决定。或不。

#5


0  

Why not something simple like this: (note this may/probably won't compile) but you get the idea...

为什么不是这样简单的东西:(注意这可能/可能不会编译)但你明白了......


private Rect* convert(const rectangle& src)
{
    return new Rect(src.x,src.y,src.w,src.h);
}
int main()
{
    rectangle r;
    r.x = 1;
    r.y = 2;
    r.w = 3;
    r.h = 4;

    Rect* foo = convert(&r);
    ...
    delete foo;

}

EDIT: Looks like koko's and I have the same idea.

编辑:看起来像koko和我有相同的想法。

#6


0  

If the structs were the same internally, you could do a reinterpret_cast; however, since it looks like you have 16-bit vs 32-bit fields, you're probably stuck converting on each call, or writing wrappers for all functions of one of the libraries.

如果结构在内部是相同的,你可以做一个reinterpret_cast;但是,由于看起来你有16位和32位字段,你可能在每次调用时都没有转换,或者为其中一个库的所有函数编写包装器。

#7


-1  

Maybe you could try it with operator overloading ? (Maybe a = operator which is not a method of your class) ?

也许你可以尝试运算符重载? (也许a =运算符不是你班级的方法)?

Rect operator= (const Rect&,const rectangle&)

Rect运算符=(const Rect&,const矩形&)

More about this in the C++ programming language by Bjarne Stroustrup or maybe on this page: http://www.cs.caltech.edu/courses/cs11/material/cpp/donnie/cpp-ops.html

有关Bjarne Stroustrup的C ++编程语言的更多信息,或者可能在此页面上:http://www.cs.caltech.edu/courses/cs11/material/cpp/donnie/cpp-ops.html