在最近的一次讨论中,我们提出了一个问题,即我们是否应该始终在类定义中完全限定当前类的名称,并在引用现有模板本身时使用显式专用模板。综上所述:
namespace foo {
struct Foo {
doSomething(foo::Foo& other); // arguably good
doSomething(Foo& other); // arguably bad
};
}
template<typename T>
struct Bar {
doSomething(Bar<T>& other); // arguably good
doSomething(Bar& other); // arguably bad
};
问题是,没有人能用确凿的事实来支持他们的说法,只是"名称查找可能出错"与"meh,从来没有任何问题。"。
为了解决这个问题:这两个约定是严格等效的,还是"坏"的约定有时会在名称查找中引入歧义参考当前的标准会非常好。
当然,不应该考虑易读性的论点,我真的在问一个符合标准的编译器在角落情况下会如何表现。然而,已知的实现错误也是受欢迎的。
https://ideone.com/f48mJI
namespace foo {
namespace foo {
typedef int Foo;
}
struct Foo {
int m_foo;
Foo( foo::Foo const& o_foo ):m_foo(o_foo.m_foo) {}
};
}
int main() {
::foo::Foo foo_(::foo::foo::Foo{});
}
总之,Foo
。
当然,在模板的情况下,它们是相同的:编译器会自动向类定义中注入类似Bar = Bar<T>
的东西。
此外,对于第一个例子,我看不出Foo
可以引用除了最本地嵌套的Foo
之外的任何东西,换句话说,就是当前类。
从功能上讲,这两者是等效的,但我要说的是,实际上它们不是:在每种情况下,越详细的一个似乎越难找到和维护。