I'm trying to write a template that returns a vector
of elements of specific type. Unfortunately I'm encountering warnings and errors that I am finding hard to resolve. I suspect I might need to use std::enable_if
rather than std::is_same_v
, but not sure of the correct way to go about it.
Below is a simplified example that reproduces the issue.
I would appreciate if someone could explain why I get the warnings and errors and how to best resolve them.
Thanks!
#include <string>
#include <vector>
#include <iostream>
struct Person
{
std::string name;
double age;
char gender;
template<class T>
std::vector<T> GetValue()
{
std::vector<T> v;
if (std::is_same_v<T, double>)
v.push_back(age);
if (std::is_same_v<T, char>)
v.push_back(gender);
if (std::is_same_v<T, std::string>)
v.push_back(name);
return v;
}
};
int main()
{
Person p{ "Joe", 33, 'm' };
std::vector<double> v1 = p.GetValue<double>();
std::cout << "double: " << v1[0] << std::endl;
// Warning with next line
std::vector<char> v2 = p.GetValue<char>();
std::cout << "char: " << v2[0] << std::endl;
// Error with next line
std::vector<std::string> v3 = p.GetValue<std::string>();
std::cout << "string: " << v3[0] << std::endl;
return 0;
}
The problem is in your GetValue()
implementation:
The push_back
statements are compiled for all the if
s, even if the value you attempt to add does not match the type T
of the vector
.
Instead you can use if constexpr
(requires C++17 on higher), so that the compiler will not compile the branches that do not satisfy the condition:
std::vector<T> GetValue()
{
std::vector<T> v;
if constexpr (std::is_same_v<T, double>)
v.push_back(age);
if constexpr (std::is_same_v<T, char>)
v.push_back(gender);
if constexpr (std::is_same_v<T, std::string>)
v.push_back(name);
return v;
}
A side note:
Your posted code is missing #include <iostream>
in order to compile.