簡體   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