Reputation: 73
I have a template function, which has no argument
template<typename T>
T cast() {
return T();
}
I want to specialize it for some templated class like vector like
template<typename T>
template<>
vector<T> cast<vector<T>>() {
// something special
return vector<T>()
}
since it takes no argument, so it cannot be overloaded. What should I do to implement it?
Upvotes: 0
Views: 88
Reputation: 217970
Functions cannot be partial specialized.
You might
provide another customization point
class which can be partial specialized:
template <typename T>
struct impl
{
T operator()() const { return T(); }
};
template <typename T>
struct impl<std::vector<T>>
{
std::vector<T> operator()() const { /*Something special*/ return std::vector<T>(); }
};
template<typename T>
T cast() {
return impl<T>{}();
}
forward to overload functions with "tag":
template <typename T>
T impl(std::struct_identity<T>)
{
return T();
};
template <typename T>
std::vector<T> impl(std::struct_identity<std::vector<T>>)
{
/*Something special*/
return std::vector<T>();
};
template<typename T>
T cast() {
return impl(std::struct_identity<T>{});
}
Create the different (exclusive) overloads (from the start):
// traits to detect std::vector
template <typename T>
struct is_vector : std::false_type {};
template <typename T, typename A>
struct is_vector<std::vector<T, A>> : std::true_type {};
template<typename T, std::enale_if_t<!is_vector<T>::value, int> = 0>
T cast() {
return T();
}
template<typename T, std::enale_if_t<is_vector<T>::value, int> = 0>
T cast() {
/*Something special*/
return T();
}
or since C++17, use if constexpr
:
// traits to detect std::vector
template <typename T>
struct is_vector : std::false_type {};
template <typename T, typename A>
struct is_vector<std::vector<T, A>> : std::true_type {};
template<typename T>
T cast() {
if constexpr(is_vector<T>::value) {
/*Something special*/
return T();
} else {
return T();
}
}
or since C++20, you might overload with constraint:
// traits to detect std::vector
template <typename T>
struct is_vector : std::false_type {};
template <typename T, typename A>
struct is_vector<std::vector<T, A>> : std::true_type {};
template<typename T>
T cast() {
return T();
}
template<typename T>
requires(is_vector<T>)
T cast() {
/*Something special*/
return T();
}
Upvotes: 2