这可能看起来有点深奥,但我有一个这样的类结构,其中单个模板类定义在与实际使用它的类不同的命名空间中。
namespace F{
template<typename>
struct Foo{
static Foo instance;
};
}
namespace B{
struct Bar{};
F::Foo<Bar> F::Foo<Bar>::instance; //error C2888
}
哪个收益率:
error C2888: 'Foo<void> Foo<void>::instance' : symbol cannot be defined within namespace 'B'
我知道这就是它应该是的样子,但在我的实例Foo
是我的库的一部分,而Bar
是由客户定义的,所以他们赢了&#39;必须是同一名称空间的一部分。定义Foo<void>::instance
的部分是宏的一部分,因此我可以隐藏用户的复杂性。
是否有任何方法可以让我从另一个命名空间内定义一个类的成员?
答案 0 :(得分:4)
针对您的特定需求的简单解决方案(假设所提供的示例代码是相关的)是使用Meyers' singleton,例如
namespace F{
template<class>
struct Foo{
static auto instance() -> Foo& {
static Foo the_instance;
return the_instance;
}
};
}
或者,您可以在头文件中提供静态成员的一般定义,由于ODR中模板的特殊豁免,该定义正常工作:
namespace F{
template<class>
struct Foo{
static Foo instance;
};
template<class Type>
Foo<Type> Foo<Type>::instance;
}
<强>修订强>:
这是最后一种方法的具体例子。它适用于g ++ 4.8.2和Visual C ++ 12.0(2013)。我记不起早期编译器版本的任何问题。
的main.cpp 的auto main() -> int {}
x.h 的
#pragma once
namespace F{
template<class>
struct Foo{
static Foo instance;
};
template<class Type>
Foo<Type> Foo<Type>::instance;
}
a.cpp 的
#include "x.h"
#include <iostream>
struct A {};
static bool u = !(std::cout << "A " << &F::Foo<A>::instance << std::endl);
#include "x.h"
a2.cpp 的
#include "x.h"
#include <iostream>
struct A {}; // Intentionally same as in file "a.cpp"
static bool u = !(std::cout << "A " << &F::Foo<A>::instance << std::endl);
b.cpp 的
#include "x.h"
#include <iostream>
struct B {};
static bool u = !(std::cout << "B " << &F::Foo<B>::instance << std::endl);
使用Visual C ++构建和运行:
H:\dev\test\so\0169>cl main.cpp a.cpp a2.cpp b.cpp /Feb main.cpp a.cpp a2.cpp b.cpp Generating Code... H:\dev\test\so\0169>b A 00988A50 A 00988A50 B 00988A6E H:\dev\test\so\0169>_