max*_*max 10 c++ sfinae c++11 template-aliases
如果替换失败涉及模板别名(例如,缺少的成员类型名称上的模板别名,如下面的代码片段中所示),是否应触发错误?
Clang和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;
}
Run Code Online (Sandbox Code Playgroud)
所以问题是:谁是正确的,为什么?
谢谢 :-)
根据标准,显然 GCC 是正确的,因为必须立即替换别名模板,然后typename T::member_type在T已知时应用正常/通常的 SFINAE 。
但目前存在一个问题,请参阅http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1554。
根据会议结果,似乎需要 clangs 行为: 的替换T将在别名模板的上下文中完成(即使在替换 in 时typename T::member_type,不再引用别名模板 - 它仍然会需要被引用作为参数类型模式起源的来源,如果这是它的实现方式)。
这类似于另一种情况,其中模式在定义时被丢弃,这可能会影响实例化语义
template<int I>
void f(int x[I]);
int main() {
f<0>(nullptr);
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,在我看来,标准在规范上很清楚,参数立即被替换int*,因此实例化工作。参见http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1322。
| 归档时间: |
|
| 查看次数: |
945 次 |
| 最近记录: |