[英]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
類。)
你可以做的一件事是將所有不同的向量放入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::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;
}
你不能有一個模板化的變量,但是你可以有一個私有的模板化方法來返回適當的變量:
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.