C++20非类型模板参数Trait判断对象类型:GCC与Clang编译分歧解析
C++20中带非类型模板参数的Trait能否判断对象所属类类型?
我尝试在C++20中通过带有非类型模板参数的Trait判断一个对象是否属于指定类类型,编写了如下代码:
#include <type_traits> template <typename T> struct wrapper { T& ref; constexpr wrapper(T& ref) : ref(ref) {} }; // 判断类型是否为`wrapper<T>`形式的Trait template <typename T> struct is_wrapper_type : std::false_type {}; template <typename T> struct is_wrapper_type<wrapper<T>> : std::true_type {}; // 判断对象是否为`wrapper<T>`类型的Trait template <auto& Value> struct is_wrapper_object; template <auto& Value> requires (!is_wrapper_type<std::decay_t<decltype(Value)>>::value) struct is_wrapper_object<Value> : std::false_type {}; template <auto& Value> requires is_wrapper_type<std::decay_t<decltype(Value)>>::value struct is_wrapper_object<Value> : std::true_type {}; int main() { static constexpr int v = 42; static_assert(!is_wrapper_object<v>::value); static constexpr wrapper w {v}; static_assert(is_wrapper_object<w>::value); }
编译差异
上述代码可在GCC中正常编译通过,但在Clang中编译失败,报错信息如下:
<source>:30:20: error: implicit instantiation of undefined template 'is_wrapper_object<v>' 30 | static_assert(!is_wrapper_object<v>::value); | ^ <source>:18:8: note: template is declared here 18 | struct is_wrapper_object; | ^ <source>:32:19: error: implicit instantiation of undefined template 'is_wrapper_object<w>' 32 | static_assert(is_wrapper_object<w>::value); | ^ <source>:18:8: note: template is declared here 18 | struct is_wrapper_object; | ^
疑问
请问哪个编译器的行为符合C++标准?我认为GCC的行为是合规的,但无法确认。
修改后的代码问题
此外,若将is_wrapper_object Trait修改为如下代码:
template <auto& Value> struct is_wrapper_object : std::false_type {}; template <auto& Value> requires is_wrapper_type<std::decay_t<decltype(Value)>>::value struct is_wrapper_object<Value> : std::true_type {};
该代码可在Clang中编译,但输出结果不符合预期。
内容的提问来源于stack exchange,提问作者nokz
相关产品推荐
相关产品推荐

