C++ 可变参数模板和隐式转换
C++ variadic templates and implicit conversions
我试图弄清楚当存在可变参数模板构造函数和转换运算符时,C++ 编译器如何解析隐式转换。这是一个最小的例子来说明:
当我写的时候:
#include <iostream>
class A {
public:
A () {}
template<typename...tTypes> A (tTypes...pArgs) {
std::cout << __PRETTY_FUNCTION__ << std::endl;
}
};
class B {
public:
operator A () const {
std::cout << __PRETTY_FUNCTION__ << std::endl;
return A();
}
};
int main() {
B b;
A a = b;
}
当 运行 我得到这个输出:B::operator A() const
。所以它正在使用转换运算符(如我所料)。 http://ideone.com/ZZ2uBz
的现场示例
但是当 A
是一个模板时,结果是不同的:
#include <iostream>
template<typename tType>
class A {
public:
A () {}
template<typename...tTypes> A (tTypes...pArgs) {
std::cout << __PRETTY_FUNCTION__ << std::endl;
}
};
class B {
public:
template<typename tType>
operator A<tType> () const {
std::cout << __PRETTY_FUNCTION__ << std::endl;
return A<tType>();
}
};
int main() {
B b;
A<float> a = b;
}
当 运行 这个程序时,我得到这个输出:A<tType>::A(tTypes ...) [with tTypes = {B}; tType = float]
。所以它使用 A
的可变参数构造函数而不是 B
中的转换运算符。 http://ideone.com/u9Rxuh
的现场示例
有人可以向我解释为什么会有所不同吗?转换运算符不应该优先于构造函数吗?
我知道我可以显式调用转换运算符 (A<float> a = b.operator A<float>();
),但这不是我想要的。
在我看来,转换不明确,其他编译器按预期失败(或者至少,这是我的预期)。以使用 clang.
的结果为例
要消除歧义,您可以显式构造函数或转换运算符。
例如,使用这个:
template<typename tType>
class A {
public:
A () {}
template<typename...tTypes> explicit A (tTypes...pArgs) { /* ... */ }
};
或者这样:
class B {
public:
template<typename tType>
explicit operator A<tType> () const { return A<tType>(); }
};
我试图弄清楚当存在可变参数模板构造函数和转换运算符时,C++ 编译器如何解析隐式转换。这是一个最小的例子来说明:
当我写的时候:
#include <iostream>
class A {
public:
A () {}
template<typename...tTypes> A (tTypes...pArgs) {
std::cout << __PRETTY_FUNCTION__ << std::endl;
}
};
class B {
public:
operator A () const {
std::cout << __PRETTY_FUNCTION__ << std::endl;
return A();
}
};
int main() {
B b;
A a = b;
}
当 运行 我得到这个输出:B::operator A() const
。所以它正在使用转换运算符(如我所料)。 http://ideone.com/ZZ2uBz
但是当 A
是一个模板时,结果是不同的:
#include <iostream>
template<typename tType>
class A {
public:
A () {}
template<typename...tTypes> A (tTypes...pArgs) {
std::cout << __PRETTY_FUNCTION__ << std::endl;
}
};
class B {
public:
template<typename tType>
operator A<tType> () const {
std::cout << __PRETTY_FUNCTION__ << std::endl;
return A<tType>();
}
};
int main() {
B b;
A<float> a = b;
}
当 运行 这个程序时,我得到这个输出:A<tType>::A(tTypes ...) [with tTypes = {B}; tType = float]
。所以它使用 A
的可变参数构造函数而不是 B
中的转换运算符。 http://ideone.com/u9Rxuh
有人可以向我解释为什么会有所不同吗?转换运算符不应该优先于构造函数吗?
我知道我可以显式调用转换运算符 (A<float> a = b.operator A<float>();
),但这不是我想要的。
在我看来,转换不明确,其他编译器按预期失败(或者至少,这是我的预期)。以使用 clang.
的结果为例要消除歧义,您可以显式构造函数或转换运算符。
例如,使用这个:
template<typename tType>
class A {
public:
A () {}
template<typename...tTypes> explicit A (tTypes...pArgs) { /* ... */ }
};
或者这样:
class B {
public:
template<typename tType>
explicit operator A<tType> () const { return A<tType>(); }
};