c – sfinae与decltype:cl ang或gcc?

c – sfinae与decltype:cl ang或gcc?,第1张

概述Clang-3.2可以按预期编译和编写行为: 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<c Clang-3.2可以按预期编译和编写行为:
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?所遇到的程序开发问题。

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

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

原文地址:https://54852.com/langs/1234591.html

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

发表评论

登录后才能评论

评论列表(0条)

    保存