【发布时间】:2013-02-22 06:43:37
【问题描述】:
我下面的示例表明,从非模板类型到模板类型的隐式转换不会像只涉及非模板类型的转换那样无缝。有没有办法让它们仍然工作?
例子:
struct point;
template<unsigned d> struct vec {
vec() { }
// ...
};
template<> struct vec<2> {
vec() { }
vec(const point& p) { /* ... */ } // Conversion constructor
// ...
};
struct point {
operator vec<2>() { return vec<2>(/* ... */); } // Conversion operator
};
template<unsigned d> vec<d> foo(vec<d> a, vec<d> b) {
return vec<d>(/* ... */);
}
template<unsigned d1, unsigned d2>
vec<d1 + d2> bar(vec<d1> a, vec<d2> b) {
return vec<d1 + d2>(/* ... */);
}
int main(int argc, char** argv) {
point p1, p2;
vec<2> v2;
vec<3> v3;
foo(v2, p1);
foo(p2, v2);
foo(p1, p2);
bar(v3, p1);
}
有没有办法让这段代码从point自动转换为vec<2>?
我知道我可以重载 foo 和 bar 以允许 point 参数,使用显式转换委托给 vec 实现。但是对所有参数组合执行此操作将变得乏味,特别是对于具有许多此类参数的函数。所以我对必须为每个函数的每个参数组合复制代码的解决方案不感兴趣。
似乎转换构造函数和强制转换运算符都不足以实现这一点。至少我的 gcc 4.7.1 报告了 no matching function call,尽管它确实在通知中命名了所需的函数,并指出 ‘point’ is not derived from ‘vec<d>’。
【问题讨论】:
-
哪一行给出了这个错误?另外,
unsigned不是 C++ 类型。 -
@James:错误是针对函数调用的行报告的,尽管通知也提到了其他各种行。随意复制和编译上面的代码,因为它是独立的。 the C++11 standard 的第 3.9.1 节命名为
unsigned,那为什么不是 C++ 类型,与 C 共享? -
不,它将
unsigned char、unsigned short int、unsigned int、unsigned long int和unsigned long long int声明为无符号整数类型。 -
但我离题了。 :) 理论上,只提供转换运算符就足够了。在
vec和point之间存在循环引用,因为它目前存在,这可能会导致编译器感到困惑。 -
我可以强制它工作的唯一变体是调用
foo<2>( v2, p1 )。顺便说一句,无需将operator vec<2>()添加到point
标签: c++ casting overloading implicit-conversion