gpt4 book ai didi

c++ - 将单个类导入命名空间似乎要求命名空间之间没有函数名称冲突

转载 作者:搜寻专家 更新时间:2023-10-31 02:14:45 26 4
gpt4 key购买 nike

由于在实例化 时对 BuildStream 的调用不明确,以下代码(令人惊讶?)无法使用 g++clang++ 进行编译bar::BuildStreambar::Rectangle 作为输入。

#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...) 需要 checkin foo 的 命名空间以及重载。

确实需要小心。您可以通过限定调用来避免歧义:

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

关于c++ - 将单个类导入命名空间似乎要求命名空间之间没有函数名称冲突,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39560477/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com