
struct have_f { int f(int i) {return 10;} }; struct empty {};template <class T> struct outer { T t; // if T have f(),define outer_f() template<class U=decltype(t.f(1))> int outer_f(int i) { return t.f(i); }};int main() { outer<have_f> o1; outer<empty> o2; // to silence unused var warning return o1.outer_f(10) + sizeof(o2); } 任何版本的GCC拒绝:
t.cc:13:6: error: ‘struct empty’ has no member named ‘f’ int outer_f(int i) { return t.f(i); } ^ 谁是正确的? Gcc或Clang?
注意,有similar question,没有真正的答案.
解决方法 我相信这个问题是14.6.3 [temp.nondep]:1 – Non-dependent names used in a template deFinition are found using the usual name lookup and bound at the point they are used.
给出的示例描述了模板定义中的形式不正确的表达“可以在模板定义中或在实例化点被诊断.
默认的template-argument(14.1p9)U = decltype(tf(1))在struct outer的实例化的上下文中是一个非依赖的名称(也就是说,它不依赖于自己模板的模板参数)所以使用T = struct为空的struct outer实例化是不正确的.该标准没有明确描述默认模板参数的评估,但唯一明确的结论是它们被视为任何其他构造,并在它们发生的时候进行评估(或者在本例中,在实例化时结构外部模板).我没有看到编译器将非依赖默认模板参数的评估延迟到SFINAE应用的上下文的任何纬度.
幸运的是,解决方案很简单:只需将默认的模板参数U作为依赖名称:
// if T have f(),define outer_f() template<class T2 = T,class U=decltype(static_cast<T2 &>(t).f(1))> int outer_f(int i) { return t.f(i); } 总结 以上是内存溢出为你收集整理的c – sfinae与decltype:cl ang或gcc?全部内容,希望文章能够帮你解决c – sfinae与decltype:cl ang或gcc?所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)