You need to use a type trait. What I mean is, the compiler knows the type when it's compiling your code, and it will apply it to the appropriately overloaded function(or constructor in this case), and you can use that to your advantage. Let's make a type trait for a vector.
//A type trait for a vector
template <typename T> struct Is_Vector { static const bool value = false; };
template <> struct Is_Vector<std::vector<T>> { static const bool value = true; };
You give the type Is_Vector
a vector type and it will have its data member value
set to true; otherwise, its data member value
will be set to false.
Now let's make a function that uses this type trait
// A function that identifies whether the argument is a vector or not
template <typename Type>
bool isVector(Type object){
return Is_Vector<Type>::value;
}
Testing it out:
int main(){
std::vector<int> vector;
int integer;
std::cout << std::boolalpha;
std::cout << isVector(vector) << '\n';
std::cout << isVector(integer) << '\n';
}
Produces true for the first function and false for the second. Best thing is, the type is figured out at compile time.
Live Demo
Alternatively, you can accomplish this using two templated functions, one of which is specialized.
//the compiler will choose this one if you pass in a vector
template <typename T>
bool isVector(std::vector<T> vector_object){
return true;
}
//the compiler will choose this one if you pass in something other than a vector
template <typename T>
bool isVector(T everything_else){
return false;
}
Live Demo