如果我想制作一个模板类,并根据模板参数的 typeid 执行不同的操作,那么我该如何编写代码?
例如,我有以下模板类,我想在其中初始化成员字段数据,具体取决于它是 int 还是 string。
#include <string>
template <class T>
class A
{
private:
T data;
public:
A();
};
// Implementation of constructor
template <class T>
A<T>::A()
{
if (typeid(T) == typeid(int))
{
data = 1;
}
else if (typeid(T) == typeid(std::string))
{
data = "one";
}
else
{
throw runtime_error("Choose type int or string");
}
}
但是,此代码无法通过以下主文件进行编译。
#include "stdafx.h"
#include "A.h"
#include <string>
int _tmain(int argc, _TCHAR* argv[])
{
A<int> one;
return 0;
}
错误是:error C2440: '=' : cannot convert from 'const char [2]' to 'int',这意味着代码实际上正在检查 else-if 语句中的 int,即使它永远不会能够到达那部分代码。
接下来,按照这个例子 ( Perform different methods based on template variable type ),我尝试了下面的 A.h 文件,但是我遇到了几个链接器错误,提示 A(void) 已经在 A.obj 中定义。
#include <string>
template <class T>
class A
{
private:
T data;
public:
A();
~A();
};
// Implementation of constructor
template <>
A<int>::A()
{
data = 1;
}
template <>
A<std::string>::A()
{
data = "one";
}
有人知道如何启动和运行这段代码吗?我还意识到在模板类中使用这样的 if-else 语句可能会削弱模板的功能。有没有更好的编码方式?
编辑:在与 Torsten 讨论后(如下),我现在有以下 A.h 文件:
#pragma once
#include <string>
// Class definition
template <class T>
class A
{
public:
A();
~A();
private:
T data;
};
// Implementation of initialization
template < class T >
struct initial_data
{
static T data() { throw runtime_error("Choose type int or string"); }
};
template <>
struct initial_data< int >
{
static int data() { return 1; }
};
template <>
struct initial_data< std::string >
{
static std::string data() { return "one"; }
};
// Definition of constructor
template <class T>
A<T>::A()
: data( initial_data< T >::data() )
{
}
和以下主要内容:
#include "stdafx.h"
#include "A.h"
#include <string>
int _tmain(int argc, _TCHAR* argv[])
{
A<int> ione;
return 0;
}
我现在得到的链接器错误是:Test template 4.obj : error LNK2019: unresolved external symbol "public: __thiscall A::~A(void)"(??1?$A@H@@QAE@XZ ) 在函数 _wmain 中引用
最佳答案
明确的特化是必经之路。
我假设您将 A.h 包含在几个 .cpp 中,这是问题的根本原因。
特化是定义,A::A() 和 A::A() 必须只有一个定义,因此它们必须只有一个 .cpp。
您必须在 .cpp 中移动显式特化
template <>
A<int>::A()
{
data = 1;
}
template <>
A<std::string>::A()
{
data = "one";
}
并在A.h中为他们保留一份声明
template<> A<int>::A();
template<> A<std::string>::A();
这样编译器就知道它们是显式特化的并且不会尝试添加自动的。
编辑:对于这四个文件,g++ m.cpp f.cpp a.cpp 没有显示任何错误。
// a.h
#define A_H
#include <string>
template <class T>
class A
{
private:
T data;
public:
A();
};
template<> A<int>::A();
template<> A<std::string>::A();
#endif
// a.cpp
#include "a.h"
template <>
A<int>::A()
{
data = 1;
}
template <>
A<std::string>::A()
{
data = "one";
}
// f.cpp
#include "a.h"
int f()
{
A<int> one;
A<std::string> two;
}
// m.cpp
#include "a.h"
int f();
int main()
{
A<int> one;
A<std::string> two;
f();
}
关于c++ - 如何对模板类中的不同模板参数执行不同的操作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11325478/