C++ 编译器与简单元函数的差异
当我尝试使用以下元函数检索元组的第一种类型时,代码可以用GCC编译,但不能用Clang编译。关于这个小片段,我有两个问题C++ 编译器与简单元函数的差异,c++,c++17,C++,C++17,当我尝试使用以下元函数检索元组的第一种类型时,代码可以用GCC编译,但不能用Clang编译。关于这个小片段,我有两个问题 这是合法的C++代码吗?为什么?或者为什么不呢 是否有一种变通方法(或正确的替代方法)可以同时适用于这两种编译器 #包括 模板 结构优先型; 模板 结构第一类型{ 使用类型=T1; }; 模板 使用first\u type\u t=typename first\u type::type; 使用元组类型1=第一个类型; 例如: 根据请求,Clang生成的错误消息: <
#包括
模板
结构优先型;
模板
结构第一类型{
使用类型=T1;
};
模板
使用first\u type\u t=typename first\u type::type;
使用元组类型1=第一个类型;
例如:
根据请求,Clang生成的错误消息:
<source>:12:1: error: implicit instantiation of undefined template 'first_type<std::tuple<int, int, double>>'
using first_type_t = typename first_type<T>::type;
^
<source>:14:21: note: in instantiation of template type alias 'first_type_t' requested here
using tuple_type1 = first_type_t<std::tuple<int, int, double>>;
^
<source>:4:8: note: template is declared here
struct first_type;
^
:12:1:错误:未定义模板“first\u type”的隐式实例化
使用first\u type\u t=typename first\u type::type;
^
:14:21:注意:在模板类型的实例化中,此处请求的别名为“first\u type\t”
使用元组类型1=第一个类型;
^
:4:8:注意:此处声明了模板
结构优先型;
^
将结构声明临时更改为(从而消除不完整的类型):
当出现差异时,通常clang是对的,MSV是错的,GCC将编译您抛出的任何东西。FWIW,您可以使用类似
的方法来代替,比如使用first\u type\u t=typename std::tuple\u element::type
@NathanOliver谢谢,我完全忽略了:templateclass T
中的DName没有用,并且在以后重新使用时有点误导。我想你可以在修复专业化后将主模板改回不完整的状态吗?@TedLyngmo这是我答案的完成吗,还是编辑建议?@Iwonderhatthisapi有很好的洞察力!我甚至没有想到要尝试这种变化,而你的解释似乎很有道理。唯一仍然缺少的是一个更正式的语句,它揭示了GCC为什么会产生错误。如果您传递-frelaxed-template-args
,则Clang会接受这一点。由于此标志启用默认禁用的标准兼容行为,GCC实际上是正确的。@TEDLYNMO他们说这是一个突破性的更改,因为措辞有缺陷。他们似乎还在等待解决办法/
template<typename>
struct first_type {};
no type named 'type' in 'first_type<std::tuple<int, int, double>>'
template<template<typename...> typename T, typename T1, typename... Ts>
struct first_type<T<T1, Ts...>> {
using type = T1;
};