error: no matching function for call to ‘to_string(std::basic_string<char>&)’

19,566

Solution 1

std::to_string only works on fundamental numeric types.

If you need a more generic function, boost::lexical_cast will work on many more types - effectively any type that can be sent to an iostream.

#include <boost/lexical_cast.hpp>

...

private_string_field = boost::lexical_cast<std::string>(value);

Solution 2

There is no to_string for basic string. It would have nothing to do.

After Benjamin Lindley's suggestion I would consider the following design, use to_string but provide default template:

#include <iostream>
#include <string>
struct Type {
  explicit operator std::string() const{
    return std::string("I am type");
  }
};

namespace std {
template <typename T>
  string to_string(const T& value) {
    return string(value);
  }
}

int main(int argc, char **argv) {
    // this is what would be in class
    Type x;
    std::string private_string_field;
    private_string_field = std::to_string(42);
    std::cout << private_string_field << std::endl;

    private_string_field = std::to_string(x);
    std::cout << private_string_field << std::endl;
    return 0;
}

By default it tries to cast the operand to a string. This way custom types can provide their own conversion. Alternative design would be to internally use stringstream and operator<< for conversions, like this:

#include <iostream>
#include <string>
#include <sstream>

struct Type {
  friend std::ostream& operator<<(std::ostream& out, const Type& value){
    return out << "Type through operator<<";
  }
};

template <class T>
std::string to_str(const T& value) {
  std::string ret;
  std::ostringstream ss;
  ss << value;
  ret = ss.str();
  return ret;
};

int main(int argc, char **argv) {
    // this is what would be in class
    Type x;
    std::string private_string_field;
    private_string_field = to_str(42);
    std::cout << private_string_field << std::endl;

    private_string_field = to_str(x);
    std::cout << private_string_field << std::endl;

    return 0;
}
Share:
19,566
ar2015
Author by

ar2015

Here is full of fools.

Updated on June 13, 2022

Comments

  • ar2015
    ar2015 almost 2 years

    Even though in a template I can have any type, the function to_string does not work on basic strings:

    for example:

    std::string str("my string");
    my_class(str);
    

    with this functor definition:

    template<class valuetype>
    void operator()(valuetype value)
    {
        ...
        private_string_field = std::to_string(value);
    

    does not work. here is the error:

    error: no matching function for call to ‘to_string(std::basic_string&)’

    What is the best way to avoid it.

    In advance, I request avoid linking to irrelevant questions just because of a few common keywords.

  • Drew Dormann
    Drew Dormann about 9 years
    This was a good analysis until the code in the question got drastically changed. :|
  • Benjamin Lindley
    Benjamin Lindley about 9 years
    Now it handles strings correctly, but not much else.
  • luk32
    luk32 about 9 years
    @BenjaminLindley Could you please elaborate? Something else needs to be "castable" to std::string. Or you mean that for example int won't work? Well an alternative would be to write a template overload for to_string that would try to cast to string it by default. Not sure if it's a better design.
  • Benjamin Lindley
    Benjamin Lindley about 9 years
    Yes, that's what I meant. It won't handle int or double or any of the other types for which there are std::to_string.overloads.
  • luk32
    luk32 about 9 years
    @BenjaminLindley I updated my answer. Not sure if it's better than Drew's (probably not) but at least it works for the cases you mentioned. Thanks for pointing it out.