模板别名和SFINAE(template aliases and sfinae)

2019-07-04 14:18发布

在涉及模板别名( 例如 ,在缺少构件类型名称的模板的别名,如在下面的代码段)的取代发生故障的情况下,应的错误触发?

锵和gcc似乎对此意见不一:

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

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

谢谢 :-)

Answer 1:

根据该标准,这显然是海湾合作委员会是正确的,因为别名模板必须立即更换,然后正常/通常SFINAE应用于typename T::member_type后,当T是已知的。

但是,目前这个问题,看http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1554 。

根据会议结果,似乎红clangs行为期望:的替代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 。



文章来源: template aliases and sfinae