首页 > 解决方案 > 在稍后的时间点确定模板类型 C++

问题描述

我正在尝试编写一些可以处理不同数据类型的通用代码。一旦设置了这些数据类型,它将在整个实例期间保持不变。

我认为展示我正在尝试做的事情会更容易,而不是描述它。

助手.h

#include <iostream>
#include <type_traits>
#include <utility>
#include <string>
#include <sstream>
#include <stdexcept>
using namespace std;
template <typename T>
class helper
{
public:
    helper()
    {
      stringstream temp;
      if(is_same<T, short>::value)
      {
        temp << 1;
      }
      else if(is_same<T,long>::value)
      {
        temp << 1024;
      }
      else if(is_same<T, char*>::value)
      {
        temp << "Hello";
      }
      else if(is_same<T, string>::value)
      {
        temp << "Hello World";
      }
      else
      {
        throw invalid_argument("Error in helper: Unknown data type" + to_string(__LINE__) +  string(__FILE__));
      }

      temp >> data;
    }


    T getData()
    {
      return data;
    }

  protected:
    T data;
};

调用.cpp

#include <iostream>
#include "helper.h"
using namespace std;

int main()
{
  helper<> my_helper;

  int data;
  cin >> data;
  switch(data)
  {
    case 1:
      my_helper = helper<short>;
      break;
    case 2:
      my_helper = helper<long>;
      break;
    case 3:
      my_helper = helper<char *>;
      break;
    default:
      my_helper = helper<string>;
      break;
  }
  cout << my_helper.getData() << endl;
  return 0;
}

现在,这不会编译,因为 helper 没有模板参数,但是有没有办法可以在稍后的时间点设置参数(比如在示例中显示的用户输入之后)?一旦设置了参数,就不会有它会改变的用例。我知道这是一个简单的例子,我可以在 中做一个coutswitch-case但这是我想要完成的概念。

不幸的是,我坚持使用 C++11 并且没有 boost 库,否则我认为我可以使用std::any,我认为我可以使用void指针,但是当我调用 a 时我必须指定数据类型是什么reinterpret_cast

如果有任何我可以提供的其他信息或我可以澄清的任何事情,请告诉我!

标签: c++c++11generic-programming

解决方案


helper<short>是一种类型,helper<char *>是另一种完全不兼容的类型。没有helper<>可以由两者分配的类型。为此,您可以使用基类:

class base {
   virtual ~base() = default;
};

template <typename T>
class helper: public base
{
    // your code
};


int main()
{
  std::unique_ptr<base> my_helper;

  int data;
  cin >> data;
  switch(data)
  {
    case 1:
      my_helper.reset(new helper<short>);
      break;
    case 2:
      my_helper.reset(new helper<long>);
      break;
    case 3:
      my_helper.reset(new helper<char *>);
      break;
    default:
      my_helper.reset(new helper<string>);
      break;
  }
  //cout << my_helper->getData() << endl;
  return 0;
}

但是我认为没有办法在virtual T getData()里面声明base


推荐阅读