繁体   English   中英

模板实例化点、依赖名称和 ADL

[英]Point of template instantiation, dependent names and ADL

我从帖子中了解到,当模板依赖名称在实例化点绑定时,使用参数依赖查找。 我理解下面的第一个简单表单,但是不确定 ADL 和绑定在第二个表单上的工作原理。 我有一个关于覆盖排序()的具体问题。

感谢是否有人可以指导我在第二个代码帖子中如何进行 ADL 和绑定。 此外,如果有办法重新定义 sort() 以不绑定到 std::sort 并绑定到其他一些实现。

template<typename T> T f(T a) {
    // Can find ::ns::g(Q) only via ADL on T for
    // an instantiation of f with T == ::ns::Q.
    return g(a);
}

namespace ns {

  class Q {};

  Q g(Q e) { return e; }

}  // namespace ns

int main() {
    (void) f(::ns::Q{});
    return 0;
}

我需要帮助的表格:

#include <iostream>
#include <vector>

template<typename T>
void print_sorted(std::vector<T>& v)
{
    //typename std::vector<T>::iterator it;
    sort(v.begin(),v.end()); // ADL looks at return type of begin()?
    for (const auto& x : v)
       std::cout << x << '\n';
}

int main(int argc, char *argv[])
{
    std::vector<std::string> v = {"b", "a"};
    print_sorted(v); // sort using std::sort, then print using std::cout
    return 0;
}

#include <algorithm> // adl of sort() would allow std::sort to be defined here

汇编:

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

我在Godbolt上尝试了 OP 的代码。 正如 OP 声称的那样,它在 Clang 下编译(而且似乎也在 GCC 上)。 如果#include <algorithm>被注释掉,两个编译器都声称他们不知道名称sort

我相信这种行为的原因是这些编译器将print_sorted function 的实例化推迟到翻译单元结束。 这样做的许可证由 C++17 [temp.point]/8 提供:

A specialization for a function template, a member function template, or of a member function or static data member of a class template may have multiple points of instantiations within a translation unit, and in addition to the points of instantiation described above, for any such在翻译单元内有一个实例化点的特化,翻译单元的末端也被认为是一个实例化点。 class 模板的特化在翻译单元内最多有一个实例化点。 任何模板的特化都可能在多个翻译单元中具有实例化点。 如果根据单一定义规则(6.2),两个不同的实例化点赋予模板特化不同的含义,则程序是非良构的,不需要诊断。

换句话说,无论function模板特化在哪里实例化,它也被认为是在翻译单元的末尾实例化,并且所有这样的实例化必须具有相同的含义,否则程序是非良构的NDR。

因此,编译器编写者可以将 function 模板实例化尽可能推迟到翻译单元结束,可能是出于效率原因,而不用担心这会改变程序的含义。 如果它确实改变了程序的含义,则意味着程序员搞砸了,编译器不需要捕捉这个错误。 (另见CWG 993

[temp.point]/8 的措辞不清楚它是否适用于 OP 的程序(因为在这里,在一个实例化点,由于使用了未声明的名称,专业化实际上是不正确的,而不是简单地具有与在另一个实例化点的含义不同)。 我认为这只是措辞上的缺陷,GCC 和 Clang 是遵循规则的“精神”。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM