本文介绍了模板别名和sfinae的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

限时删除!!

如果涉及模板别名的替换失败(例如,缺少成员类型名称的例如模板别名,如下面的代码片段所示),是否应该触发错误?

In the case of a substitution failure involving a template alias (e.g. a template alias on a missing member typename, as in the code snippet below), should an error be triggered ?

Clang和gcc似乎对此持不同意见:

Clang and gcc seem to disagree on this:

// some types
struct bar { };

struct foo {
    typedef void member_type;
};


// template alias
template<class T>
using member = typename T::member_type;


template<class T>
void baz(... ) { }

// only works for gcc, clang fails with: no type named 'member_type'
// in 'bar'
template<class T>
void baz( member<T>* ) { }


int main(int, char** ) {

    baz<bar>(0);            // picks first
    baz<foo>(0);            // picks second

    return 0;
}

所以问题是:谁是正确的,为什么?

So the question is: who is correct, and why ?

谢谢:-)

推荐答案

根据标准,显然GCC是正确的,因为必须立即替换别名模板,然后将普通/常用的SFINAE应用于typename T::member_type稍后,当T已知时.

According to the Standards, it is clearly GCC that is correct, because the alias template must immediately be replaced and then normal/usual SFINAE is applied to typename T::member_type later when T is known.

但是目前存在一个问题,请参见 http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1554 .

But there currently is an issue for this, see http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1554.

根据会议结果,似乎是需要c语的行为:T的替换将在别名模板的上下文中完成(即使在typename T::member_type中进行替换时,也没有引用)别名模板-仍然需要作为参数类型模式的来源来引用(如果是这样实现的).

According to the meetings outcome, it appears that clangs behavior is desired: The substitution of T will be done in the context of the alias template (even though at the time of substitution in typename T::member_type, there is no reference to the alias template anymore - it will still need to be referenced as the source of where the parameter type pattern originated from, if this is how it's implemented).

这类似于另一种情况,在定义时间丢弃模式可能会影响实例化语义

This is similar to another situation where patterns are thrown away on definition time that could influence instantiation semantics

template<int I>
void f(int x[I]);

int main() {
  f<0>(nullptr);
}

在这种情况下,我认为标准在规范上也很清楚,该参数立即被int*替换,因此实例化起作用.参见 http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1322 .

In this case too, in my opinion the Standard normatively is clear that the parameter is immediately being replaced by int* and thus the instantiation works. See http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1322 .

这篇关于模板别名和sfinae的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

1403页,肝出来的..

09-06 08:28