簡體   English   中英

C ++替代模板化數據成員

[英]C++ Alternative to templatized data member

如果我有一個類DataManager

class DataManager
{
 public:
   int getRecordInt( size_t i ) const;
   std::string getRecordString( size_t i ) const;

 private:
   std::vector<int> _vInt;
   std::vector<std::string> _vString;
}

我可以用例如訪問記錄

DataManager DM;
// .. populate object ...
int iValue = DM.getRecordInt(3);

在我的實際應用程序中,我將有超過一百種數據類型(除了int和std :: string),所以我想避免為每種類型編寫單獨的getter。

現在,如果C ++支持模板化的變量名稱(它不支持),我可以將類實現為:

class DataManager
{
 public:
   template<typename T>
   T getRecord( size_t i ) const
   {
      return _v<T>[i];
   }

 private:
   std::vector<int> _v<int>;
   std::vector<std::string> _v<std::string>;
}

有什么方法可以達到C ++的目的嗎?

(請注意,盡管我已將示例簡化為最小化,但我的實際問題要復雜得多,並且需要存在此類DataManager類。)

C ++ 14解決方案:

你可以做的一件事是將所有不同的向量放入std::tuple 然后你可以使用std::get來指定從元組中獲取哪個向量,然后訪問該向量。 那看起來像

class DataManager
{
 public:
   template<typename T>
   T getRecord( size_t i ) const
   {
      return std::get<std::vector<T>>(_v)[i];
   }

 private:
   std::tuple<std::vector<int>, std::vector<std::string>> _v{{1,2,3},{"a","b","c"}};
};

int main()
{
    DataManager d;
    std::cout << d.getRecord<std::string>(2);
}

哪個輸出

c

實例

如果你的類型只出現一次,你可以使用std::tuplestd::get

class DataManager
{
public:
   template<typename T>
   T getRecord( size_t i ) const
   {
      return std::get<std::vector<T>>(v)[i];
   }

 private:
   std::tuple<std::vector<int>, std::vector<std::string>> v;
}

你不能有一個模板化的變量,但是你可以有一個私有的模板化方法來返回適當的變量:

class DataManager
{
 public:
   template<typename T>
   T getRecord( size_t i ) const
   {
      return _v<T>()[i];
   }

 private:
   std::vector<int> _vInt;
   std::vector<std::string> _vString;
   template<typename T> std::vector<T>& _v() {
       throw std::logic_error("non managed type");
   }
};

template <> std::vector<int>& DataManager::_v<int>() {
   return _vInt;
}
template <> std::vector<std::string>& DataManager::_v<std::string>() {
   return _vString;
}

您可以自行決定是否為您的實際用例提供可接受的解決方案。

如果Serge Ballesta的答案沒有漂浮你的船(恕我直言,這是正確的方式繼續),那么你可以咬緊牙關寫一個宏(C ++ 03解決方案):

#define ADD_RECORD_TYPE(TYPENAME, QUALIFIED_TYPENAME) \
private: \
    std::vector<QUALIFIED_TYPENAME> _v##TYPENAME; \
public:  \
    QUALIFIED_TYPENAME get_record_##TYPENAME(size_t i) const{return _v##TYPENAME.at(i);}

class DataManager
{
    ADD_RECORD_TYPE(string, std::string)
    ADD_RECORD_TYPE(int, int)
};
#undef ADD_RECORD_TYPE

演示

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM