繁体   English   中英

如何从模板类中的typename传递中创建新的typename

[英]How to create new typename from the typename pass in a template class

假设我有一个模板类

template <class DATA>
class Stack { 
  //Some implementation
}

在这个堆栈类中,我正在调用一个实用程序类,它也是模板。 但是其处理的数据类型为UltityDATA类型。 那就是如果我们使用以下代码创建类堆栈的对象

 stack<MyData> s

在内部,它应该调用UltityMyData 我不想向客户端公开UltityMyData结构。 我已经编写了将MyData覆盖到UltityMyData的实现。 唯一的要求是在我调用库类时如何将DATA类型名称转换为UtilityDATA类型名称。


根据您的建议,我编写了以下代码

#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将其作为新数据类型而不是模板类型。

您可以使用traits模式:

template <class DATA, class TRAITS>
class Stack 
{ 
  //Some implementation
}

并像这样实例化:

stack<MyData, UtilityMyData> s;

但是,这将要求您的用户显式命名实用程序类。 如果您不介意使用预处理器,则可以使用宏:

#define STACK(T) Stack<T, Utility##T>

然后您会写:

  STACK(MyData) s;

这不是很漂亮,但是您的用户可能会接受

也许您可以将其移至某些内部模板结构?

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

您可以根据需要拥有一个专门用于类型定义的结构

// 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
    // .....
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM