Reputation: 4355
I'm implementing a flatten()
method for a struct that receives an std::vector
.
I want the flatten()
method to only be available if MyStruct
is constructed with an std::vector<std::vector<Type>>
, and not when it's constructed with std::vector<Type>
(and Type
is not an std::vector
, of course).
It did manage to make it work, except for CLANG. Depending on how I implement I get different errors.
I'd like to know the proper way of doing this with enable_if
.
The signature of my struct should look similar to this:
template <typename Type>
struct MyStruct {
...
// this should only exist if Type is an std::vector
MyStruct<Type::value_type> flatten() {
...
}
}
Upvotes: 0
Views: 193
Reputation: 106530
Why do you need enable_if for this? Plain ol' type deduction is for you:
template <typename T>
MyStruct<vector<T>> flatten(const MyStruct<vector<vector<T>>>& input) {
// ...
}
EDIT: For your updated question, you really really probably want to use a nonmember here. It is a simpler API for your customers and given what this thing is doing, flatten probably doesn't need access to MyStruct's private bits, and if it doesn't need access to private bits it should be a non-member non-friend.
If for some reason you want to do this thing, you could write a trait for it using a free function, and then static_assert inside, similar to:
http://melpon.org/wandbox/permlink/W0NG1VxX4fuia8kM
or
http://melpon.org/wandbox/permlink/UJZ7qliuAqXLSW4b
#include <vector>
#include <type_traits>
template <typename T>
std::false_type is_vector_of_vector_helper(const T&); // not defined
template <typename T>
std::true_type is_vector_of_vector_helper(const std::vector<std::vector<T>>&);
template <typename T>
using is_vector_of_vector_t = decltype(is_vector_of_vector_helper(std::declval<T>()));
template <typename T>
struct MyStruct {
MyStruct<typename T::value_type> flatten() const {
static_assert(is_vector_of_vector_t<T>::value,
"Flatten should only be called with MyStruct<vector<vector<T>>>");
// impl
return {};
}
};
Upvotes: 3