如何在C++中通过using声明暴露模板基类的模板转换运算符?
在C++11及以上暴露基类模板转换运算符的可行方案
在C++11及以上标准中,确实可以暴露基类的模板转换运算符,但你原代码中的using声明语法不符合规范。以下是两种可靠的实现方式:
方法一:通过转发函数显式暴露
这种方式兼容性最好,所有支持C++11的编译器都能正常编译。在派生类B中定义一个模板转换运算符,直接调用基类的对应运算符:
template <typename T> struct B : protected A<T> { public: using A<T>::A; // 暴露构造函数 using A<T>::operator(); // 暴露函数调用运算符 // 转发基类的模板转换运算符 template <typename V> operator A<V>() const { // 利用protected继承的访问权限,直接调用基类转换运算符 return static_cast<const A<T>&>(*this).operator A<V>(); } };
修改后,main中static_cast<A<double>>(B<int>(10))()的代码就能正常编译运行。如果需要让B<int>直接转换为B<double>,还可以额外添加:
template <typename V> operator B<V>() const { return static_cast<A<V>>(*this); }
方法二:使用模板using声明(部分编译器支持)
C++11允许对模板成员进行using声明,但需要调整语法以消除歧义。这种写法在GCC、Clang中支持较好,MSVC需使用较高版本的标准:
template <typename T> struct B : protected A<T> { public: using A<T>::A; using A<T>::operator(); // 正确的模板转换运算符using声明 template <typename V> using A<T>::template operator A<V>; };
这里的template关键字用于明确告知编译器operator A<V>是基类A<T>的模板成员,避免语法解析错误。
修改后的完整示例代码
template <typename T> struct A { private: T _t; public: A(T t) : _t(t) {} T operator()() const { return _t; } template <typename V> operator A<V>() const { return _t; } }; template <typename T> struct B : protected A<T> { public: using A<T>::A; using A<T>::operator(); // 方法一:转发实现(注释后可启用方法二) template <typename V> operator A<V>() const { return static_cast<const A<T>&>(*this).operator A<V>(); } // 方法二:模板using声明 // template <typename V> // using A<T>::template operator A<V>; }; int main() { int w = A<int>(10)(); double x = static_cast<A<double>>(A<int>(10))(); int y = B<int>(10)(); double z = static_cast<A<double>>(B<int>(10))(); // 正常编译 return 0; }
内容的提问来源于stack exchange,提问作者rubikssolver4
相关产品推荐
相关产品推荐

