函数的重载解析取决于模板参数

lar*_*sch 0 c++ templates overloading

在下面的示例中,函数模板 ( quartic) 使用重载的全局函数 ( square)。编译时,仅考虑在模板本身之前声明的重载,因此square(int)使用 so 而不是square(double),即使square(double)在使用模板之前声明也是如此。

int square(int);

template<typename T>
T quartic(T value) {
    return square(square(value));
}

double square(double);

double x(double y) {
    return quartic(4.0); // Uses square(int), wanted square(double)
}
Run Code Online (Sandbox Code Playgroud)

有没有一种方法可以根据square使用模板时可用的内容来决定哪个重载版本,以便用户可以实现他使用的square任何类型?T

注意:奇怪的是,MSVC 将使用square(double),而 GCC、clang 和 icc 使用square(int)

Red*_*Fog 5

insquare函数模板quartic是一个从属名称,这意味着它依赖于模板参数T,并且其查找会被推迟,直到T知道为止。此外,它是一个非限定名称限定名称看起来像),这意味着它不仅会在其名称空间中查找,还会在参数的名称空间std::cout中查找,这称为参数相关查找ADL

所以在这种情况下:

  • 非 ADL 查找检查具有从模板定义上下文中可见的外部链接的函数声明。(原因在[1]中有解释)
  • ADL检查具有从模板定义上下文模板实例化上下文中可见的外部链接的函数声明。

显然,不允许您的示例通过非 ADL 查找来工作。ADL也不考虑,因为ADLdouble不考虑。

但如果参数是用户定义的类型,则按ADL工作。更清楚地说,如果您想调用 this 作用域后面定义的函数,您可以通过 ADL 使该函数可见,这意味着该函数和参数的类型(或间接类型,请参阅[2])位于同一名称空间中。

参考:

  1. https://en.cppreference.com/w/cpp/language/dependent_name
  2. https://en.cppreference.com/w/cpp/language/adl