gpt4 book ai didi

c++ - typename 定义 map 数据时的类型名称, map 数据是带有少量模板的函数指针

转载 作者:行者123 更新时间:2023-11-30 02:09:32 25 4
gpt4 key购买 nike

这是一个奇怪的问题,因为我已经知道“编码”的答案。我只是想更好地理解为什么会这样。这里有专家比 C++ 标准更擅长解释这些事情 :)

下面我们有一个方法来定义一个抽象工厂模板,它根据一个字符串作为键来分配对象(这是一个人为的例子):-

#include <iostream>
#include <map>
#include <string>

using namespace std;

template <typename T, typename TProduct>
TProduct *MyFactoryConstructHelper(const T *t)
{
if (!t) return new T;
return new T(*static_cast<const T*>(t));
}

template <typename TProduct>
class AbstractFactory
{
public:
typedef TProduct *(*MyFactoryConstructor)(const void *);
typedef map<string, MyFactoryConstructor> MyFactoryConstructorMap;

static TProduct *Create(const string &iName)
{
MyFactoryConstructor ctr = mTypes[iName];
TProduct *result = NULL;
if(ctr) result = ctr(NULL);
return result;
}

template <typename T>
static bool Register(const string &iName) {
typedef TProduct*(*ConstructPtr)(const T*);
ConstructPtr cPtr = MyFactoryConstructHelper<T, TProduct>;
string name = iName;
mTypes.insert(pair<string,MyFactoryConstructor>(name, reinterpret_cast<MyFactoryConstructor>(cPtr)));
return(true);
}

protected:
AbstractFactory() {}
static MyFactoryConstructorMap mTypes;
};

template <typename TProduct>
map<string, /*typename*/ AbstractFactory<TProduct>::MyFactoryConstructor> AbstractFactory<TProduct>::mTypes;

这是我们如何使用它的示例:-

class MyProduct
{
public:
virtual ~MyProduct() {}

virtual void Iam() = 0;
};

class MyProductFactory : public AbstractFactory<MyProduct>
{
public:
};

class ProductA : public MyProduct
{
public:
void Iam() { cout << "ProductA" << endl; }
};

class ProductB : public MyProduct
{
public:
void Iam() { cout << "ProductB" << endl; }
};

int _tmain(int argc, _TCHAR* argv[])
{
MyProduct *prd;
MyProductFactory::Register<ProductA>("A");
MyProductFactory::Register<ProductB>("B");

prd = MyProductFactory::Create("A");
prd->Iam();
delete prd;
prd = MyProductFactory::Create("B");
prd->Iam();
delete prd;

return 0;
}

它不会按原样编译,提示 map 没有数据类型的有效模板类型参数。但是,如果您删除静态成员定义中“typename”关键字周围的注释,一切都会编译并正常工作……为什么?

还有,我可以改进一下吗? :)

最佳答案

该标准试图允许一个实现来解析和读取模板时尽可能多地检测模板中的错误模板定义,在任何实例化之前。 C++ 不是然而,上下文无关,如果不是的话,这非常困难不可能,如果你不知道就正确地解析语句哪些符号是类型,哪些是模板。如果符号是相关的(在某种程度上取决于模板参数),您必须告诉编译器它是类型还是模板;否则,编译器必须假设它是别的东西。在这种情况下,您是在告诉编译器AbstractFactory::MyFactoryConstructor 命名一个类型,而不是别的。

如果,当模板被实例化时,编译器可以看到符号真正绑定(bind)的是什么,事实证明你撒谎了(例如 AbstractFactory::MyFactoryConstructor 实际上是一个 int),那么编译器就会生你的气。

另请注意,AbstractFactory 已定义在需要 typedef 的定义没有改变之前任何事物。总是可以有一个明确的特化您在其上实例化 AbstractFactory 的类型。

关于c++ - typename 定义 map 数据时的类型名称, map 数据是带有少量模板的函数指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5335095/

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