Reputation: 85
I have a Template function taking in const types such as:
template <class T, class U>
void process(const T& v1, const U& v2)
{
//do some things
verify(v1);
verify(v2);
}
Then the verify function checks the Type for T using if constexpr as follows: (The function also returns the variable. I set it to auto for the purpose of this question)
template <class T>
auto verify(const T& t)
{
if constexpr (is_same_v<T, int>)
return t;
if constexpr (is_same_v<T, string>)
return t;
if constexpr (is_same_v<T, double*>)
return t;
else
static_assert(false, "Type not allowed");
}
if the type is not found it will trigger a compilation error. This all works very fine but the problem is I would like to make v2 a non-const U& parameter. This triggers the static_assert and I don't know why. I also set all parameters in both functions to non-const but I still get the same error. All I really want is to pass the arguments by reference. Can anyone give me some hints? Thanks in advance.
Upvotes: 0
Views: 1134
Reputation: 29955
A better way of doing that would be to static_assert
some type trait:
#include <string>
#include <type_traits>
template <class T, class... Y>
inline bool constexpr is_one_of =
(std::is_same_v<std::decay_t<T>, std::decay_t<Y>> || ...);
template <class T>
void verify() {
static_assert(is_one_of<T, int, std::string, double*>);
}
template <class T, class U>
void process(T const& v1, U const& v2) {
verify<T>();
verify<U>();
// ...
}
Upvotes: 1
Reputation: 179779
This is one of those things you'd need to know.
The form you're looking for is
template <class T> auto verify(T&& t) {
The reason is that T
can be const U
, a const-qualified type. The double &&
is necessary for rvalue references.
You probably want std::is_same_v<std::remove_cv_t<T>>, ...
And to simply things:
template <class T> auto verify(T&& t)
{
using baseT = std::remove_cv_t<T>;
static_assert(is_same_v<baseT, int> ||
is_same_v<baseT, string> ||
is_same_v<baseT, double*>);
return t;
}
Upvotes: 2