考虑以下程序:
template<typename T>
constexpr int f()
{
T{}.i; // error if instantiated with [T = double]
return 42;
}
constexpr void g(char);
using U = decltype( g( {f<double>()} ) );
据我了解,最后一行是一个错误,因为调用f<double>()
是在大括号初始化程序中,即使f<T>
返回 a int
,也需要返回的值int
来确定它是否可以char
按预期缩小到 a g
。这需要f
用 实例化的定义double
,这会导致错误。gcc 和 clang 都拒绝此代码。
但是,如果将 的定义g
更改为接受int
参数:
constexpr void g(int);
那么似乎不需要实例化 的定义f
,因为缩小转换必须成功。事实上,gcc 接受了这一点,但 clang 仍然实例化f
并double
拒绝代码。此外,如果f
仅声明但未定义,clang 接受代码,这意味着不需要定义,也不应实例化。
我的推理是否正确,这是一个clang错误,还是需要实例化,这实际上是一个gcc错误?