假设我有一个模板类
template <class DATA>
class Stack {
//Some implementation
}
在这个堆栈类中,我正在调用一个也是模板的实用程序类。但是其处理的数据类型是UltityDATA类型。也就是说,如果我们使用以下代码
创建类堆栈的对象 stack<MyData> s
在内部,它应该调用 UltityMyData 。我不想将UltityMyData结构暴露给客户端。我已经编写了将MyData转换为UltityMyData的实现。只有我的要求是当我调用我的库类时如何将DATA typename转换为UtilityDATA typename。
我根据你的建议编写了以下代码
#include <iostream>
#include <vector>
#include <cstdlib>
#include <string>
#include <stdexcept>
using namespace std;
struct RTI
{
int a;
};
struct DDSRTI
{
int b;
};
// other specialization you might need in the future
template<class Data>
struct DDS
{
typedef DDSData type;
};
template <class T>
class MyStack {
private:
T a;
public:
MyStack()
{
// cout<< a;
}
};
#define STACK(T) Stack<DDS##T>
template <class T>
class Stack {
private:
Stack<T> a;
STACK(T) b;
public:
Stack()
{
///cout<< a;
}
};
但我收到错误错误:'DDST'未在此范围内声明
基本上预处理器只附加两个值并创建一个新类型。根据我的理解,模板将在编译时进行转换。 DDS#T将其作为新数据类型而非模板类型。
答案 0 :(得分:0)
您可以使用traits
模式:
template <class DATA, class TRAITS>
class Stack
{
//Some implementation
}
和instanciate像这样:
stack<MyData, UtilityMyData> s;
但是,这将要求您的用户明确命名实用程序类。如果您不介意使用预处理器,可以使用宏:
#define STACK(T) Stack<T, Utility##T>
然后你会写:
STACK(MyData) s;
它不漂亮,但您的用户可能会接受
答案 1 :(得分:0)
也许您可以将其移至某个内部模板结构?
template <class DATA>
class Stack {
public:
template <class Data>
struct UtilData {
template <class... Args>
UtilData(Args&&... args) : d{std::forward<From>(args)...} {}
// other operators
Data d;
};
void push(DATA&& d) {
s.push(UtilData<DATA>{d});
}
std::stack<UtilData<DATA>> s;
};
更新:对不起,我误解了你的问题。对于某些具体类型MyData和UtilMyData,您可以使用boost :: mpl :: map:
using boost::mpl::pair;
using boost::mpl::map;
using boost::mpl::at;
typedef map<pair<SomeOther, Some>/*, other pairs of types here*/> TypeMap;
at<TypeMap, SomeOther>::type s; // s has type Some
答案 2 :(得分:0)
您可以根据需要设置一个专门定义类型定义的结构
// non specialized type
template<typename T>
struct UtilType {};
// specialization for DATA
template<>
struct UtilType<DATA>
{
typedef UtilityDATA type;
};
// other specialization you might need in the future
template<>
struct UtilType<NewType>
{
typedef UtilityNewType type;
};
然后你将使用这个助手类
template<typename T>
class Stack
{
// .....
typedef typename UtilType<T>::type dataType; //converts DATA typename to UtilityDATA
// .....
}