code using core issue 2118: 为什么Clang看不到函数定义?

Code using core issue 2118: why doesn't Clang see the function definition?

示例代码(取自here [uses core issue 2118,稍作修改):

#include <type_traits>

template<int N> struct tag{};

template<typename T, int N>
struct loophole_t
{
    friend auto loophole(tag<N>) { return T{}; };
};

auto loophole(tag<0>);

struct detector
{
    template <typename T, int = sizeof(loophole_t<T, 0>)>
    operator T();
};

template <typename T, int = sizeof(T{detector{}})>
constexpr auto get_type()
{
    return loophole(tag<0>{});
}

typedef double T;

struct test
{
    T x;
};

int main(void)
{
    static_assert( std::is_same<T, decltype(get_type<test>())>::value, "xxx" );
    return 0;
}

调用:

$ gcc t0.cpp -std=c++14 -pedantic -Wall -Wextra
<nothing>

$ icc t0.cpp -std=c++14 -pedantic -Wall -Wextra
<nothing>

$ clang t0.cpp -std=c++14 -pedantic -Wall -Wextra
<source>:22:12: error: function 'loophole' with deduced return type cannot be used before it is defined
    return loophole(tag<0>{});
           ^
<source>:11:6: note: 'loophole' declared here
auto loophole(tag<0>);

$ cl t0.cpp /std:c++14 /Za
<nothing>

为什么 Clang 看不到函数定义?标准是怎么说的?

在你的代码中

return loophole(tag<0>{});

不依赖于模板参数。我目前不确定标准是否要求在模板定义时推导 loophole(tag<0>{}) 的类型,这将使​​程序 ill-formed,但即使没有,这也是 ill-formed,不需要诊断

[temp.res.general]/8.4 要求模板 get_type 的假设实例在其定义后立即不应是 ill-formed 由于 non-dependent 构造。但是,如上所述,由于缺少推断占位符 [=32] 所需的 loophole 的定义,此时对 loophole(tag<0>{}) 的调用是 non-dependent 并且可能是 ill-formed =] 类型,如果不使用默认模板参数。