簡體   English   中英

GCC和Clang模板調用分辨率差異

[英]GCC and Clang template call resolution differences

給出以下代碼:

#include <iostream>

struct Alice
{
  template <typename A>
  void operator|(const A& /*a*/) const
  {
    std::cout << "operator| member" << std::endl;
  }
};

template <typename A>
void operator|(const A& /*a*/, const Alice& /*alice*/)
{
  std::cout << "operator| non-member" << std::endl;
}

int main()
{
  Alice a;
  Alice b;

  a | b;

  return 0;
}

使用GCC 4.8.1、4.9和clang 3.4編譯時不會發出警告,但結果卻不同。

$ g++ -Wall -Wextra -std=c++11 alice.cpp && ./a.out
operator| non-member

$ clang++ -Wall -Wextra -std=c++11 alice.cpp && ./a.out
operator| member

是什么原因導致這種差異? 我該如何強制相同的行為?

編輯:有趣的事實:從成員函數中刪除const限定詞使gcc也更喜歡成員函數。 但是,它不能解決問題。

編輯:如果未指定-std=c++11 ,則clang ++首選使用非成員。

編輯: ICC 14.0首選非會員,不會發出警告。

根據重載解決方案,有兩個可行的功能:全局operator|的專業化operator| 具有推論參數的-template和成員運算符函數模板的特殊化。 兩者都具有相同的簽名-成員函數模板具有類型為Alice const&的隱式對象參數(請參見§13.3.1/ 4)。

因此,兩個可行的函數(扣除模板參數后)都具有相同的簽名。 實例化它們的模板中的任何一個都不比另一個更專業。 因此,這確實是模棱兩可的,因此是不正確的。 令人驚訝的是,VC ++是正確的。

我該如何強制相同的行為?

也許您應該只是消除歧義,然后Clang,VC ++和GCC應該具有相同的行為。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM