How can I tell the compiler that U
is equivalent to either std::vector<T>
or T
?
template<typename T, typename U> std::vector<T> foo(T t, U){return t;}
CodePudding user response:
I found a solution by myself.
It seems could be achieved by std::enable_if
. Is there any better way?
#include <iostream>
#include <vector>
template<typename T, typename U, typename = typename std::enable_if<
std::is_same< T, U >::value || std::is_same<std::vector<T>, U>::value>::type>
std::vector<int> foo()
{
std::cout << "on the move!\n";
return {};
}
int main()
{
foo<int, int>();
foo<int, std::vector<int>>();
//foo<int, float>(); //does not compile, in expectation.
}
#include <iostream>
#include <vector>
#include <functional>
template<typename T, typename U, typename = typename std::enable_if<
std::is_same< T, U >::value || std::is_same<std::vector<T>, U>::value>::type>
void foo(std::function<U(void)> func)
{
std::cout << "on the move!\n";
}
int main()
{
foo<int>(std::function<int(void)>());
foo<int>(std::function<std::vector<int>(void)>());
//foo<int>(std::function<float(void)>()); //does not compile, in expectation.
}
CodePudding user response:
I'm not sure if this is better or worse than your proposed solution, but you can try using template specialization, which is similar to function overloading. This would look like this
// Generic function
template<typename T, typename U> std::vector<T> foo(T t, U u) { // Do something}
// First specialization for the case of U == T
template<typename T> std::vector<T> foo(T t, T u) { // Do something}
// Second specialization for the case of U == std::vector<T>
template<typename T> std::vector<T> foo(T t, std::vector<T> u) { // Do something}
A possible downside of this approach is the possibility of repeating code, which violates the DRY principle. As such, if your objective is to simply constraint your arguments without needing to change the function definition, then this answer may be better suited for such application.