I have a C++ function that looks like this:
template <class T> void MyClass::set(T value) {
if (std::is_same<T, std::string>::value) {
stringValue_ = value;
} else if (std::is_same<T, int>::value) {
intValue_ = value;
}
}
assigning to 'int' from incompatible type 'std::__cxx11::basic_string<char>'
You cannot cast a template parameter, in the manner you're trying to do:
template <class T> void MyClass::set(T value) {
if (std::is_same<T, std::string>::value) {
stringValue_ = value;
} else if (std::is_same<T, int>::value) {
intValue_ = value;
}
}
The key concept here is that a template function gets expanded in its entirety when it gets instantiated.
If say, for a given template instance, the T
template parameter is an integer. This template then get instantiated in approximately the following manner:
void MyClass::set(int value)
{
if (false)
{
stringValue_=value;
}
Your attempt here to set stringValue
, that's presumably a std::string
, to an int
, is not going to be very successful. Just because the if
condition is false, does not make this chunk of code go away. It still must be valid C++, even if it never gets executed, and this is not valid C++. This is the explanation for your compilation error.
Some features in the newest C++17 standard will make these kinds of constructs actually possible. However, pre-C++17 the general approach to solving this kind of a problem is to use template specialization:
template<typename T> void MyClass::set(T value);
template<> void MyClass::set<int>(int value)
{
intValue_=value;
}
template<> void MyClass::set<std::string>(std::string value)
{
stringValue_=value;
}
Or, forget templates entirely, and just define two separate set()
methods.