gpt4 book ai didi

c++ - 为什么(或何时)模板引入其命名空间?

转载 作者:行者123 更新时间:2023-12-04 16:59:04 26 4
gpt4 key购买 nike

下面是一个例子:

#define MAKE_IT_WORK false
namespace Bob { // Bob's project namespace
struct DeviceFrequency {};
extern void debugf(const char* fmt, ...);
} // namespace Bob

namespace SSN { // Super-Secret Namespace
namespace debugging {
extern int ssn_debug;
extern void debugf(const char* fmt, ...);
} // namespace debugging
} // namespace SSN

namespace SSN::signals { // Super-Secret Namespace, project signals
template<typename Coder> // In the example, this imports Bob's namespace
class Frequency {
public:
Frequency( void )
{ using namespace ::SSN::debugging; // Why isn't this enough??
using ::SSN::debugging::debugf; // Or this??
if( ssn_debug )
#if MAKE_IT_WORK
::SSN::debugging:: // How can a developer predict that this is needed??
#endif
debugf("Frequency(%p,%zd)::Frequency\n", this, sizeof(*this));
}
}; // class Frequency
} // namespace SSN::signals

struct Controller {
SSN::signals::Frequency<Bob::DeviceFrequency> bobcon;
Controller( void ) : bobcon() {}
}; // class Controller
在这个例子中,Bob 复制了 debugf函数,因为他不想将整个 SSN 命名空间带入他的私有(private)命名空间,也不想在每次使用时都为完全限定它而烦恼。
SSN 开发人员没有意识到模板也可以导入其命名空间(直到它发生),显然使 ADL 查找发挥作用。尽管 ADL 查找声明命名空间中的 using 语句被忽略,但为什么它起作用根本没有意义。一个命名空间无意中污染另一个命名空间似乎太容易了,而且很难预测有一天会在内联代码中出现这种情况。
看起来(至少)每当在命名空间中使用模板时,每个命名空间函数引用都必须是完全限定的,因为在使用模板时,您无法预测何时可能会发生名称冲突。这个对吗?如果是这样,有没有办法避免所有似乎需要的额外名称限定符输入?这种暴露仅限于模板,还是所有导入的内联代码都以某种方式同样容易受到攻击?
使用 gcc 版本 10.2.0 和 10.2.1 (Red Hat 10.2.1-5) 编译 (Dirty.cpp),我收到以下消息:
make dirty 
c++ -o Dirty.o -c S/Dirty.cpp -D_CC_GCC -D_OS_BSD -D_HW_X86 -D_OS_LINUX -IS -IH -g -O3 -finline->functions -std=gnu++17 -Wall -Wextra -Wmissing-declarations -Wswitch-default -Werror
S/Dirty.cpp: In instantiation of ‘SSN::signals::Frequency<Coder>::Frequency() [with Coder = Bob::DeviceFrequency]’:
S/Dirty.cpp:146:32: required from here
S/Dirty.cpp:139:12: error: call of overloaded ‘debugf(const char [30], SSN::signals::Frequency<Bob::DeviceFrequency>*, long unsigned int)’ is ambiguous
139 | debugf("Frequency(%p,%zd)::Frequency\n", this, sizeof(*this));
| ~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
S/Dirty.cpp:124:13: note: candidate: ‘void SSN::debugging::debugf(const char*, ...)’
124 | extern void debugf(const char* fmt, ...);
| ^~~~~~
S/Dirty.cpp:117:13: note: candidate: ‘void Bob::debugf(const char*, ...)’
117 | extern void debugf(const char* fmt, ...);
|

(已编辑:该示例已恢复为原始版本,现在由@1201ProgramAlarm 重新格式化。出现了一个修改版本,用于测试以下部分答案中的示例。)

最佳答案

对于模板,ADL 包括与
为模板类型参数提供的模板参数的类型。因为调用了debugf包括 this作为参数,ADL 将包括 namespace Bob因为模板是用 Bob::DeviceFrequency 实例化的.

关于c++ - 为什么(或何时)模板引入其命名空间?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64563430/

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