考虑以下程序:
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错误?