具有不同实例化的多个实例化点?

时间:2020-07-21 22:52:07

标签: c++

我有一些带有多个实例化点的代码,其中Stroustrup C ++声明“如果可以通过选择不同的实例化点来构造两种不同的含义,则程序是非法的。也就是说,如果依赖项或非依赖项的绑定名称可以不同,该程序是非法的。“。

有人知道为什么编译器没有捕获到这个吗?

谢谢

void f(int) {}

namespace N {
    class X { };
    char g(X,int) {return 0;}
}

template<typename T> char ff(T t, double d)
{
    f(d); // f is bound to f(int)
    return g(t,d); // g might be bound to g(X,int)
}
auto x1 = ff(N::X{},double{1.1});

namespace N {
    char g(X,double) {return 0;}
}

auto x2 = ff(N::X{},double{2.2});

int main(int argc, char *argv[])
{
    return 0;
}

编译:

clang++ -pedantic -Wall -std=c++11 test188.cc && ./a.out

Compilation finished at Tue Jul 21 18:48:29

1 个答案:

答案 0 :(得分:3)

有人知道为什么编译器没有捕获到这个吗?

来自[temp.point]/8

函数模板,成员函数模板或类模板的成员函数或静态数据成员的专业化可以在转换单元内具有多个实例化点,并且除了上述实例化点之外,对于翻译单元中具有实例化点的任何此类专业化,翻译单元的末尾也被视为实例化点。类模板的专门化在翻译单元中最多具有一个实例化点。任何模板的专业化可能在多个翻译单元中具有实例化点。 如果两个不同的实例化点根据一个定义规则为模板专门化赋予不同的含义,则程序格式错误,无需诊断。

违反此规则的程序格式错误,但无需诊断。因此,不需要编译器实现通过编译器错误来标记这种格式不正确的程序。