Gui*_*cot 16 c++ language-lawyer clang++ c++17
今天我正在阅读clang的C++ 17支持页面.我注意到一些奇怪的事情.功能匹配模板模板参数与兼容参数(P0522R0)标记为部分,因为它必须通过开关激活.他们的笔记说:
尽管是缺陷报告的解决方案,但默认情况下,此功能在所有语言版本中都被禁用,并且可以使用Clang 4中的标志-frelaxed-template-template-args显式启用.标准的更改缺少相应的更改对于模板部分排序,导致合理且先前有效的代码的模糊错误.预计这个问题很快就会得到纠正.
激活此功能后会出现什么样的构造?为什么它会破坏代码?
Rak*_*111 14
您可以使用以下代码:
template<template<typename> typename>
struct Foo {};
template<typename, typename = void>
struct Bar {};
Foo<Bar> unused;
Run Code Online (Sandbox Code Playgroud)
如果没有缺陷解决方案,unused则会形成错误,因为foo模板只有一个模板参数,而不是两个.如果您依赖于此(可能是SFINAE):
template<template<typename> typename>
void foo();
template<template<typename, typename> typename>
void foo();
template<typename, typename = void>
struct Bar {};
int main() {
foo<Bar>(); // ambiguous after resolution!
}
Run Code Online (Sandbox Code Playgroud)
然后电话会失败!问题是部分排序没有相应的变化,因此两个候选函数具有相同的可行性,并且调用是不明确的.
更常见的情况是某些代码想要使用一组部分特化来检查模板参数,例如:
template<class> struct Foo;
template<template<class> class X, class T>
struct Foo<X<T>> { /* ... */ };
template<template<class, class> class X, class T, class U>
struct Foo<X<T, U>> { /* ... */ };
// etc., etc.
Run Code Online (Sandbox Code Playgroud)
Foo<std::vector<int>> 如果没有适当的部分订购修复,现在形成不良.