0

I am new to c++ templates. I am having trouble converting a templated member object to std::string. My code below fails to print the character 'c' (on my machine it prints 'R' instead) and I can't find a way to make it work. Is there a way to do this when using char as type T?

#include <iostream>
#include <string>

template<class T>
class A {
    public:

    T t;
    A(T t1):t{t1}{};

    std::string toString(){
        return "" + static_cast<char>(t); 
    };
};


using namespace std;

int main()
{
    A<char> a{'c'};
    cout << a.toString() <<"\n";
    return 0;
}
ga38xab
  • 3
  • 1

3 Answers3

0

Change

return "" + static_cast<char>(t); 

to

return std::string() + static_cast<char>(t); 

With the original, you have a string literal treated as a pointer.

Daniel Langr
  • 22,196
  • 3
  • 50
  • 93
  • 1
    Or `return std::string(1, static_cast(t));` – Some programmer dude Jan 07 '20 at 09:18
  • Thank you, this worked, although I don't really understand, why. Can you explain the difference? – ga38xab Jan 07 '20 at 09:20
  • @ga38xab String literal has a type of plain char array, which, when used with arithmetic, is treated as a pointer. The result of the expression is, therefore, some `const char*` value incremented by the integer value of `t`. The resulting pointer is invalid, which causes undefined behavior. You need the operator `+` to be applied to `std::string` objects instead of pointers. A compiler won't create it for you, hence you need to do this manually. – Daniel Langr Jan 07 '20 at 09:24
0

If std::string is constructible from T you can use the following solution:

#include <iostream>
#include <string>

template<class T>
class A {
    public:

    T t;
    A(T t1):t{t1}{};

    std::string toString(){
        return {t}; // <- this constructs a string from t
    };
};


using namespace std;

int main()
{
    A<char> a{'c'};
    cout << a.toString() <<"\n";
    return 0;
}

Live code here.

However this will fail if std::string is not constructible from T. In that case you can use template specialisation to handle the conversion properly.

Community
  • 1
  • 1
florestan
  • 4,405
  • 2
  • 14
  • 28
0

The problem with

return "" + static_cast<char>(t);

is that "" isn't a std::string object, it's a literal string which is a constant array of characters. As an array it will decay to a pointer to its first element, and you add static_cast<char>(t) to the pointer.

This new pointer will then be used as a null-terminated string to create a std::string object, and that usage of the invalid pointer leads to undefined behavior.

You can construct a std::string directly from a single character and return it as

return std::string(1, static_cast<char>(t)); 
Some programmer dude
  • 400,186
  • 35
  • 402
  • 621