And*_*rei 14 c++ gcc templates clang visual-c++
我不明白有什么问题:无论是在我的代码中还是在编译器中(不太可能)。有一段代码是这样的:
#include <iostream>
#include <type_traits>
#include <set>
template<typename T, typename = void>
struct TestA: std::false_type {};
template<typename T>
struct TestA<T, std::void_t<typename T::reverse_iterator>> : std::true_type {};
template<typename T>
struct TestA<T, std::void_t<typename T::dummy_iterator>> : std::true_type {};
int main()
{
std::cout << TestA<std::set<int>>::value;
}
Run Code Online (Sandbox Code Playgroud)
GCC 和 MSVC 都会编译它。我使用不同版本的 GCC 和 MSVC 17(本地)和 19 在 Godbolt 上对其进行了测试。这是一个链接:https ://godbolt.org/z/Enfm6L 。
但是 Clang 不编译它并发出错误:
#include <iostream>
#include <type_traits>
#include <set>
template<typename T, typename = void>
struct TestA: std::false_type {};
template<typename T>
struct TestA<T, std::void_t<typename T::reverse_iterator>> : std::true_type {};
template<typename T>
struct TestA<T, std::void_t<typename T::dummy_iterator>> : std::true_type {};
int main()
{
std::cout << TestA<std::set<int>>::value;
}
Run Code Online (Sandbox Code Playgroud)
我很感兴趣 - 也许标准的某些部分这段代码不正确,或者其他地方。
这很可能与CWG 1558相关。
17.6.7 [temp.alias] 的当前措辞未指定别名模板特化中未使用参数的处理。例如:
Run Code Online (Sandbox Code Playgroud)#include <iostream> template <class T, class...> using first_of = T; template <class T> first_of<void, typename T::type> f(int) { std::cout << "1\n"; } template <class T> void f(...) { std::cout << "2\n"; } struct X { typedef void type; }; int main() { f<X>(0); f<int>(0); }
对 first_of 的引用与 T 是 int 等效于简单的 void,还是替换失败?
这是一个已被解决的缺陷,但如果您使用的 Clang 版本尚未实现修复,它可能仍然认为这两个特化只是将第二个参数定义为void
,而不是执行整个替换失败的讨论。解决方法是不使用普通别名std::void_t
,而是使用稍微复杂的版本
template <typename...> struct voider { using type = void; };
template <typename... T> using my_void_t = typename voider<T...>::type;
Run Code Online (Sandbox Code Playgroud)
对于类模板(即别名现在所代表的含义),定义了替换失败。将其插入到您的示例中可以安抚 Clang https://godbolt.org/z/VnkwsM。
归档时间: |
|
查看次数: |
500 次 |
最近记录: |