Triggered by a comment to this answer I would like to write (in C++11) a
template <typename T>
struct has_out_op { static const bool value = ???; }
to dis/enable a member function depending on std::cout << t;
being valid for some T t
. I came this far...
#include <iostream>
struct can_convert_to_base{}; // but does not when there is a better match
struct base {base(can_convert_to_base);};
template <typename T>
auto test(const T& t,can_convert_to_base)
-> decltype( std::cout << t);
template <typename T>
std::false_type test(const T& t,base);
template <typename T>
struct has_out_op {
static const bool value =
!std::is_same<std::false_type,
decltype( test(T(),can_convert_to_base()) )
>::value;
};
struct A{};
int main() {
std::cout << has_out_op<int>::value; // prints 1
std::cout << has_out_op<A>::value; // prints 0
}
This seems to work, but when I use it for what I was actually aiming for:
struct B {
template <typename T>
typename std::enable_if<has_out_op<T>::value,B&>::type operator<<(const T& t) {
std::cout << t;
return *this;
}
};
int main() {
B b;
b << "1";
}
I get the error
prog.cc: In instantiation of 'const bool has_out_op<char [2]>::value':
prog.cc:25:60: required by substitution of 'template<class T> typename std::enable_if<has_out_op<T>::value, B&>::type B::operator<<(const T&) [with T = char [2]]'
prog.cc:31:14: required from here
prog.cc:17:67: error: functional cast to array type 'char [2]'
decltype( test(T(),can_convert_to_base()) )
^
prog.cc: In function 'int main()':
prog.cc:31:11: error: no match for 'operator<<' (operand types are 'B' and 'const char [2]')
b << "1";
^
Then I realized that my has_out_op
requires T
to be default constructible, and since that I am turning in circles. When I have a value I can easily test
if std::cout << t;
is valid, but with the type alone I have no idea how to properly implement has_out_op
.
How to detect if there is a matching overload for std::cout << t;
given only decltype(t)
?
Note that I already know how to dis/enable B::operator<<
properly, but out of courisity I am still struggling with getting has_out_op
right.
Aucun commentaire:
Enregistrer un commentaire