myW*_*SON 3 c++ gcc templates visual-studio-2010 c++11
我无法在gcc中的简单代码上访问受保护的基类型typedef :
#include <iostream>
#include <memory>
#include <map>
template <class X>
X& Singleton()
{
static X x;
return x;
}
template<class GUID_T, class MAP_T, class T>
class TypeFactory {
protected:
bool ContainsInternal(MAP_T id) {
auto it = types.find(id);
return (it != types.end());
}
typedef GUID_T GUID;
inline virtual MAP_T GetTypeID(GUID guid) = 0;
std::map<MAP_T, T> types;
public :
void Add(GUID guid, const T & value) {
auto id = GetTypeID(guid);
if(!ContainsInternal(id)) {
types.insert(std::make_pair(id, T(value)));
}
}
bool Contains(GUID guid) {
return ContainsInternal(GetTypeID(guid));
}
std::shared_ptr<T> Get(GUID guid) {
auto id = GetTypeID(guid);
std::shared_ptr<T> result;
auto it = types.find(id);
if(it != types.end()) {
result = std::make_shared<T>(it->second);
}
return result;
}
std::map<MAP_T, T> & GetAll() {
return types;
}
};
template<class T>
class IntTypeFactory : public TypeFactory<int, int, T> {
protected:
inline virtual int GetTypeID(GUID guid) {
return guid;
}
};
class Type {
public: int a;
};
int main() {
IntTypeFactory<Type> & Types (Singleton< IntTypeFactory<Type> >());
IntTypeFactory<Type> & Types2 (Singleton< IntTypeFactory<Type> >());
auto t_in = Type();
t_in.a = 10;
Types.Add(1, t_in);
auto t_out = Types2.Get(1);
std::cout << t_out->a << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
编译并适用于VS2010 btw ...并且如果我真的声明inline virtual int GetTypeID(int guid) {那么适用于GCC那么我 的GCC代码有什么问题如何让它看到受保护的父类typedef?
您必须限定GUID类型名称.编译器不会在基类中查找非限定名称,并且由于它既不在全局命名空间中可用,也不在类型别名中IntTypeFactory,它最终会抱怨GUID成为不存在类型的名称:
template<class T>
class IntTypeFactory : public TypeFactory<int, int, T> {
protected:
inline virtual int GetTypeID(
typename TypeFactory<int, int, T>::GUID guid) {
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
return guid;
}
};
Run Code Online (Sandbox Code Playgroud)
MSVC不实现模板的两阶段查找,并且总是在实例化时查找名称,这就是VS2010编译的原因.但是,此行为不符合标准.GCC是正确的.