如何编译错误"调用'to_string'没有匹配函数"的程序?C++



如果我在这里有DATA_T = std::string,我不能编译这段代码,因为错误"没有匹配的函数来调用'to_string'"。该函数不允许将字符串转换为字符串。但我需要得到字符串无论如何,我怎么能解决这个错误和编译程序?

template <typename DATA_T>
std::string get_string(DATA_T subdata) {
std::string data = "...";
if (typeid(subdata) == typeid(std::string))
data += subdata;
else
data += std::to_string(subdata);
return data;
}

在c++ 17中,使用if constexpr:

可以使它更简单
#include <string>
#include <type_traits>
template <typename DATA_T>
std::string get_string(DATA_T subdata) {
std::string data = "...";
if constexpr (std::is_same_v<DATA_T, std::string>)
data += subdata;
else
data += std::to_string(subdata);
return data;
}

参见c++ 17之前的解决方案的另一个答案。

与其在函数体中分支模板实参的类型,不如编写一个重载,当实参是std::string时优先使用。

template <typename DATA_T>
std::string get_string(DATA_T subdata) {
std::string data = "...";
data += std::to_string(subdata);
return data;
}
std::string get_string(std::string subdata)
{
std::string data = "...";
data += subdata;
return data;
}

如其他答案所示,可以为std::string添加一个特例。这将解决您的std::string问题,但其他类型如何?

当我第一次看到to_string时,我很失望,因为它只有有限的重载集。然而,我误解了to_string是什么意思。它意味着将转换为字符串,就像std::sprintf使用正确的格式说明符所做的那样。由于sprintf继承自C语言,它不能将c++中可以转换为字符串的所有类型转换为字符串。没有办法通过sprintf直接启用自定义类型的转换。正因为如此,to_string也有同样的限制。特别是没有to_string(const std::string&)

重载std::ostream& operator<<(std::ostream&,const T&)更灵活。你想用foo还是bar来调用get_string?为什么不:

#include <iostream>
#include <sstream>
template <typename DATA_T>
std::string get_string(DATA_T subdata) {
std::stringstream data;
data << "...";
data << subdata;
return data.str();
}
struct foo {};
std::ostream& operator<<(std::ostream& out,const foo& f){
return out << "foo";
}
int main() {
foo f;
std::cout << get_string(f);
}

如果你真的想像sprintf那样转换,我可能会继续使用其他答案中提出的解决方案之一。

最新更新