C++ 使用空格从std::stringstream提取流

C++ 使用空格从std::stringstream提取流,c++,c++17,C++,C++17,我有一个模板函数,它从std::map中获取一个元素作为字符串,通过std::stringstream操作符>>将其转换为泛型T,并返回它 但是,提取操作符仅提取流中的第一个单词 我已经尝试了.str(),但是对于模板函数,它不起作用。我还尝试了ss>>std::noskipws>>结果但它似乎没有返回有效数据 模板 T CConfig::get(常量字符*设置) { std::stringstream-ss; ss m_设置[设置]; //此->m_设置[设置]=“这是一个测试” T结果; s

我有一个模板函数,它从
std::map
中获取一个元素作为字符串,通过
std::stringstream操作符>>
将其转换为泛型
T
,并返回它

但是,提取操作符仅提取流中的第一个单词

我已经尝试了
.str()
,但是对于模板函数,它不起作用。我还尝试了
ss>>std::noskipws>>结果但它似乎没有返回有效数据

模板
T CConfig::get(常量字符*设置)
{
std::stringstream-ss;
ss m_设置[设置];
//此->m_设置[设置]=“这是一个测试”
T结果;
ss>>结果;
//result=“this”
返回结果;
}

我的期望是,如果m_settings[setting]是
“这是一个测试”
,那么在我的
get
函数中将返回相同的字符串。同时,我不想通过硬编码
ss.str()
和对字符串使用不同的函数来破坏模板。

您必须准确地决定字符串的行为。如果要提取整行,可以使用
std::getline()
。或者在这种情况下,可能只是
返回此->m_设置[设置]

无论您最终做什么,解决方案都是将变体行为转化为
get
的专业化


只需小心,专业行为不会偏离主代码太远,因为这可能会让您的用户(包括您自己!)感到困惑。

您必须准确地确定字符串的行为。如果要提取整行,可以使用
std::getline()
。或者在这种情况下,可能只是
返回此->m_设置[设置]

无论您最终做什么,解决方案都是将变体行为转化为
get
的专业化

只需小心,专业行为不会偏离主代码太远,因为这可能会让您的用户(包括您自己!)感到困惑。

以下是三种方法:

  • 正如我在评论中所说,您可以专门化函数
    get
    并从那里调用
    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;
    }
    
  • 这里有三种方法:

  • 正如我在评论中所说,您可以专门化函数
    get
    并从那里调用
    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;
    }
    

  • 如果您的目标是读取以换行符结尾的文本行,这就是
    std::getline()
    的用途
    >
    是用于错误作业的错误工具。
    std::getline()
    在我使用例如
    get
    时会破坏行为,然后对使用
    std::getline()
    @0x499602D2的
    get
    进行专门化,您应该编写一个答案;如果你的目标是阅读一行以换行符结尾的文本,这就是
    std::getline()
    的目的
    >
    是用于错误作业的错误工具。
    std::getline()
    在我使用例如
    get
    时会破坏行为,然后对使用
    std::getline()
    @0x499602D2的
    get
    进行专门化,您应该编写一个答案;不要在评论中给出解决方案,因为它不能被适当的同行评审。如果没有专业化,这怎么会不起作用呢<代码>模板std::string get(const char*setting)
    -我在CPPFreference上找不到这种用法的示例unfortunately@shavit字符串的专门化是
    template std::string get(const char*setting)
    @shavit,如果您只需搜索“cppreference template specialization”。或者,转到C++的关于专业化模板专业的页面,这怎么会不起作用?代码>模板std::string get(const char*setting)
    -我在CPPFreference上找不到这种用法的示例unfortunately@shavit字符串的专门化是
    template std::string get(const char*setting)
    @shavit,如果您只需搜索“cppreference template specialization”。或者,转到C++的关于模板专业的书中的页面。
    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;
    }