簡體   English   中英

將單個類導入命名空間似乎要求命名空間之間沒有函數名沖突

[英]Importing a single class into a namespace appears to require that there be no function name collisions between the namespaces

由於在使用bar::Rectangle作為輸入實例化bar::BuildStream時對BuildStream調用不明確,以下代碼(令人驚訝的是?)無法使用g++clang++編譯。

#include <iostream>
#include <sstream>

namespace foo {

struct Rectangle { double height, width; };
std::ostream& operator<<(std::ostream& os, const Rectangle& a) { return os; }

inline void BuildStream(std::ostringstream& os) { }

template<typename T, typename... Args>
void BuildStream
(std::ostringstream& os, const T& item, const Args& ...args) {
  os << item;
  BuildStream(os, args...);
}

} // namespace foo

namespace bar {

inline void BuildStream(std::ostringstream& os) { }

template<typename T, typename... Args>
void BuildStream
(std::ostringstream& os, const T& item, const Args& ...args) {
  os << item;
  BuildStream(os, args...);
}

using Rectangle = foo::Rectangle;

} // namespace bar

int main(int argc, char* argv[]) {
  std::ostringstream os;
  bar::BuildStream(os, 1, 2);
  bar::BuildStream(os, bar::Rectangle(), bar::Rectangle());
  return 0;
}

歧義似乎意味着,一般來說,如果一個類從命名空間foo導入到命名空間bar ,那么必須注意確保bar中的函數的名稱不與foo函數名稱相同。 這顯然破壞了命名空間的一些好處; 有沒有更細致的方法來避免這種歧義?

上下文是foo是一個大型庫的命名空間, bar是一個消費者項目的命名空間(這個問題在實踐中出現了)。

這里的問題是與參數相關的查找。 bar::Rectangle實際上是一個foo::Rectangle ,所以調用BuildStream(os,args...)需要檢查foo's命名空間以及重載。

確實需要小心。 您可以通過限定調用來避免歧義:

  template<typename T, typename... Args>
  void BuildStream(std::ostringstream& os, const T& item, const Args& ...args)
  {
    os << item;
    bar::BuildStream(os, args...); // qualified
  }

暫無
暫無

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

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