c如何为类的模板化转换运算符指定参数

c如何为类的模板化转换运算符指定参数,第1张

概述我正在尝试为类的模板转换运算符指定模板参数,但我似乎无法使语法正确. #include <iostream>using namespace std;class C{ int i_;public: C(int i) : i_(i) {} template<int adder> int get() { return i_ + adder; } template<in 我正在尝试为类的模板化转换运算符指定模板参数,但我似乎无法使语法正确.

#include <iostream>using namespace std;class C{   int i_;public:   C(int i) : i_(i) {}   template<int adder> int get() { return i_ + adder; }   template<int adder> int operator()() { return i_ + adder; }   template<int adder> operator int() { return i_ + adder; }    // If I add a default argument to operator int()'s adder template parameter this compiles fine    // (of course,I still can't figure out how to specify it...)};int main(int,char*[]){   C c(10);   cout << c.get<2>() << endl;            // I can specify template argument here the regular way.//   cout << c() << endl;                 // No template argument specifIEd,so I wouldn't have expected this to work.   cout << c.operator()<3>() << endl;     // We have to call it this way.//    cout << (int)c << endl;             // In the same vein I wouldn't expect this to work either.   cout << c.operator int<4>() << endl;   // But how do I specify template argument here? This seems to be an error for some compilers.   return 0;}

http://liveworkspace.org/code/35sqXe$4的相同代码

用g 4.7.2编译时

$g++ -std=c++11 -Wall -W -pedantic "template conversion operator.cpp"Compilation finished with errors:source.cpp: In function 'int main(int,char**)':source.cpp:23:23: error: 'int' is not a templatesource.cpp:23:30: error: no matching function for call to 'C::operator int()'source.cpp:23:30: note: candIDate is:source.cpp:11:24: note: template<int adder> C::operator int()source.cpp:11:24: note: template argument deduction/substitution Failed:source.cpp:23:30: note: Couldn't deduce template parameter 'adder'

用g 4.8.0(20130224)编译时

$g++ -std=c++11 -Wall -W -pedantic "template conversion operator.cpp"Compilation finished with errors:source.cpp: In function 'int main(int,char**)':source.cpp:23:23: error: 'int' is not a template    cout << c.operator int<4>() << endl;                        ^source.cpp:23:30: error: no matching function for call to 'C::operator int()'    cout << c.operator int<4>() << endl;                              ^source.cpp:23:30: note: candIDate is:source.cpp:11:24: note: template<int adder> C::operator int()    template<int adder> operator int() { return i_ + adder; }                        ^source.cpp:11:24: note: template argument deduction/substitution Failed:source.cpp:23:30: note: Couldn't deduce template parameter 'adder'    cout << c.operator int<4>() << endl;                              ^

用clang 3.2编译时

$clang++ -std=c++11 -Wall -W -pedantic "template conversion operator.cpp"Compilation finished with errors:source.cpp:23:12: error: reference to non-static member function must be called   cout << c.operator int<4>() << endl;           ^~~~~~~~~~~~~~source.cpp:23:30: error: expected Expression   cout << c.operator int<4>() << endl;                             ^2 errors generated.

用icc 13.0.1编译时

$icc -std=c++11 -Wall -W -pedantic "template conversion operator.cpp"Compilation finished with warnings:source.cpp(11): warning #488: constant "adder" is not used in declaring the parameter types of function template "C::operator int"     template<int adder> operator int() { return i_ + adder; }                  ^

除了警告之外,icc似乎工作正常.

这些编译器错误吗?或者是我的语法是问题?

编辑

因为Yakk问我的原始/实际问题是什么:
我有一个类Ptr(根据它指向的类型进行模板化),我希望将Ptr转换为const T.(尽管我知道在这种情况下无关紧要),我希望转换运算符不是如果T已经是const类型,那就在那里.由于您没有为转换运算符指定返回类型或方法参数,因此我将enable_if作为方法模板参数的一部分.

正如Yakk(以及其他问题中的其他人)发布的那样,一个简单的模板< typename = typename std :: enable_if<!std :: is_const< T> :: value> :: type>不起作用,因为当Ptr被实例化时,T在编译器获得此声明时就已知.由于没有推断出T,因此没有SFINAE.由于我们知道!is_const< T> :: value为false,因此没有“type”成员且声明无效.使模板依赖于新类型(U),推导出U,然后检查U是否与T相同,并且T不是const,然后具有无效声明是SFINAE的有效使用并且有效正如所料.

template <typename T>class Ptr{   template <typename U,typename = typename std::enable_if<std::is_same<T,U>::value &&                                                !std::is_const<U>::value>::type>   operator Ptr<const U>() const { return active; }};

但后来我对自己说,这是一个模板化的成员函数.这些模板参数不必保留其默认值,可以由实例化该函数的任何人指定.对于任何其他运算符xxx函数,执行此 *** 作的语法很明显并且有效(请参阅上面的operator()).对于这个例子:

Ptr<const int> ci;ci.operator Ptr<const int><const int,voID>(); // assuming this Syntax is valID

voID(或其他任何类型)将指定转换运算符的第二个模板参数,并且不会考虑包含enable_if的默认值.当我试图让它不存在时,这将使这种方法存在.

但gcc,clang和msvc似乎似乎有这种语法的问题.我假设由于转换运算符拼写为运算符typename,因此使用模板参数会让编译器误以为它们是类型名而不是运算符.

确实存在变通方法(只包括转换运算符,当T已经是const时,转换为const T并没有伤害任何变量),但这是针对这个特定问题的.也许不可能为转换运算符指定模板参数,因此保留这些类型可以推导/默认是可以的.或者可能有一个语法(icc似乎采取它…),所以我打开自己指定模板参数和实例化我不想要它们的方法.我已经有针对我的特定问题的解决方案(在转换运算符中对类型确实重要的时间使用类型检查时使用static_assert),但这个问题是关于C语言及其语法.顶部的C类是我能想到的最简单的搜索语法的方法.

解决方法 你有点不清楚你想要实现的目标……一般来说,没有任何理由让所有这些成员函数成为模板,你也可以将它们作为参数加入常规函数.

get函数,实际上并没有得到,而是添加,所以你可以称之为add.函数调用运算符operator()()很可能将int作为参数.转换运算符到int在字面上没有意义作为模板,并且不能在定义时调用.如果您坚持将get和operator()作为模板,则可以将它们称为:

C c(0);c.get<5>(); // 5c<5>();     // 5

但我建议你重新考虑设计,决定你真正需要什么以及模板是否可行……(请注意,即使在非模板化版本中,转换为int也没有意义一个值,你不是转换,而是创建一个不同的int!)

总结

以上是内存溢出为你收集整理的c如何为类的模板化转换运算符指定参数全部内容,希望文章能够帮你解决c如何为类的模板化转换运算符指定参数所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1226582.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-05
下一篇 2022-06-05

发表评论

登录后才能评论

评论列表(0条)

保存