[英]Stream extracting from std::stringstream with spaces
我有這個模板函數,它以字符串的形式從std::map
獲取元素,然后通過std::stringstream operator>>
將其轉換為通用T
並返回它。
但是,提取運算符僅提取流中的第一個單詞。
我已經嘗試過.str()
,但是對於模板功能卻無法做到。 我也嘗試過ss >> std::noskipws >> result;
但它似乎未返回有效數據。
template<typename T>
T CConfig::get(const char *setting)
{
std::stringstream ss;
ss << this->m_settings[setting];
// this->m_settings[setting] = "this is a test"
T result;
ss >> result;
// result = "this"
return result;
}
我的期望是,如果m_settings [setting]為"this is a test"
,則將在我的get
函數中返回相同的字符串。 同時,我也不想通過對ss.str()
進行硬編碼ss.str()
字符串使用其他函數來破壞模板。
您必須准確確定想要字符串的行為。 如果要提取整行,可以使用std::getline()
。 或者在這種情況下,也許只return this->m_settings[setting];
。
無論您最終做什么,解決方案都是將變體行為歸類為get<std::string>
的特殊化 。
請注意,專用行為與主代碼的行為不會相差太遠,因為這可能會使您的用戶(包括您自己!)感到困惑。
這是3種方式:
就像我在評論中說的那樣,您可以專門使用get<std::string>
函數, get<std::string>
從那里調用std::getline()
。
template<typename T> T CConfig::get(const char* settings) { std::istringstream stream(m_settings[settings]); T t; assert(stream >> t); return t; } template<> std::string CConfig::get<std::string>(const char* settings) { std::istringstream stream(m_settings[settings]); T t; assert((std::getline(stream, t))); return t; }
這種方法的缺點是它會導致代碼重復。
委托給使用主要和專用重載的輔助函數。
template<typename T> T CConfig::get(const char* settings) { T t; assert( do_get(std::istringstream(m_settings[settings]) >> std::skipws, t); ); return t; } template<typename T> bool do_get(std::istringstream& stream, T& data) { return stream >> data; } template<> bool do_get(std::istringstream& stream, std::string& data) { return std::getline(stream, data); }
如果您有c ++ 17,則只需使用if constexpr
:
template<class T> T CConfig::get(const char* settings) { T t; std::istringstream stream(m_settings[settings]); if constexpr(std::is_same_v<T, std::string>) { assert((std::getline(stream, t))); } else { assert(stream >> t); } return t; }
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.