I wrote a template wrapper that should find out if the class owns the function.
template<typename...>
using void_t = void;
template <typename ,typename = void>
struct has_member:std::false_type{};
template<typename T>
struct has_member<T, void_t<decltype(std::declval<T>().push_back())>>:std::true_type{};
But I can't figure out how to apply it correctly.I tried at first like this:
template<typename T, bool = has_member<T>::value>
void foo(T& container) {
std::cout << "i here";
}
But everything goes there, i.e. even if there is no push_back function:
std::set<int> st;
foo(st); // okey
Tried to change to:
template<typename T,typename std::enable_if_t< has_member<T>::value ,int>* = nullptr >
void foo(T& container) {
std::cout << "i here";
}
But together with such a function call
std::vector<int> vc(10);
foo(vc);
I get a few errors:
Error (active) E0304 no instance of function template "foo" matches the argument list
Error C2672 'foo': no matching overloaded function found
Error C2783 'void foo(T &)': could not deduce template argument for '__formal'
I'd happy some help to figure out what I did wrong .
Also. Can all structures be replaced with?
template<typename T>
using has_type = decltype(std::declval<T>().push_back());
I also did not get an insert in the function (with the same errors as above)
I use a vector there and expected that it will pass
The problem is in std::declval<T>().push_back()
, there's no push_back
taking nothing for std::vector
.
You need to pass argument to push_back
, e.g.
template<typename T>
struct has_member<T, void_t<decltype(std::declval<T>().push_back(std::declval<typename T::value_type>()))>>:std::true_type{};
And about why the 1st solution doesn't work, because when has_member<T>::value
is true
, the instantiation foo<T, true>
gets called, otherwise foo<T, false>
gets called, both are valid.