模板别名和sfinae

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

铿锵和海湾合作委员会似乎不同意这一点:

// 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;
}

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

谢谢 :-)


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

但目前有一个问题,请参阅http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1554。

根据会议结果,看起来叮当行为是理想的: T的替换将在别名模板的上下文中完成(即使在typename T::member_type ,也没有对别名的引用模板 - 它仍然需要被引用作为参数类型模式来源的来源,如果这是它的实现方式的话)。


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

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。

链接地址: http://www.djcxy.com/p/66669.html

上一篇: template aliases and sfinae

下一篇: Client Request parameters of generated classes