在ADL,“本地”或全局命名空间以外的命名空间中定义函数

时间:2016-04-04 11:44:23

标签: c++ namespaces argument-dependent-lookup

请参阅以下代码:

#include <iostream>

/// Definition of void perform(a_lib::a_class&). Where should I put this definition?
/// See the comments below for where I've tried placing it.
// void perform(a_lib::a_class&) {
//   std::cout << "performing on a_lib::a_class" << std::endl;
// }

namespace a_lib {
  class a_class {  };

  // WORKS HERE but it pollutes a_lib (namespace of third-party library).
}

namespace mine {
  // DOESN'T WORK HERE: "use of undeclared identifier 'perform'".
}

// WORKS HERE but it pollutes the global namespace.

namespace b_lib {
  // WORKS HERE but it pollutes b_lib (namespace of third-party library).

  template <typename Type>
  void b_func(Type& obj) {
    perform(obj);
  }
}

namespace mine {
  // DOESN'T WORK HERE: "use of undeclared identifier 'perform'".

  void run() {
    a_lib::a_class a_obj;
    b_lib::b_func(a_obj);
  }
}

int main(int, char**) {
  mine::run();

  return 0;
}

a_libb_lib是属于两个不同第三方库的命名空间。 mine是我自己的命名空间。

我被告知污染全局命名空间是个坏主意,在this question他们也说过向std添加类型是一个坏主意。我认为后者对于命名空间来说是正确的;您不应该将类型添加到不属于您的命名空间。

但是如何在不违反这些原则的情况下解决上述问题呢?我应该在哪里放置perform()的定义以及如何让b_func()来调用它?

上下文:我正在尝试在我自己的命名空间中为cereal类型添加外部SFML序列化()。这是一个简化的例子。

1 个答案:

答案 0 :(得分:0)

您需要确定编译器在处理“b_func”时可以找到“执行”的位置。

namespace mine {
  // DOESN'T WORK HERE: "use of undeclared identifier 'perform'".

  // dom -  yes it will, but there is 'more' to the name than your example shows

  void perform(Type& obj) { /* do something with obj */}

}

// WORKS HERE but it pollutes the global namespace.

namespace b_lib {
  // WORKS HERE but it pollutes b_lib (namespace of third-party library).

  // dom -  use here is easy with correct and 'more-complete' name:

  template <typename Type>
  void b_func(Type& obj) {  mine::perform(obj); }
  // -----------------------^^^^^^^^^^^^^^^^^^^ --- more to name
}

由于“我的”是名称空间,因此名称空间可以“覆盖”更完整的名称。

请注意,在mine :: perform()实现中,还必须定义“Type”以使用obj。