По комментарию к этому ответу Я хотел бы написать (в C ++ 11)
template <typename T>
struct has_out_op { static const bool value = ???; }
, чтобы отключить / включить функцию-член в зависимости от std::cout << t;
быть действительным для некоторых T t
.Я зашел так далеко ...
#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
}
Кажется, это работает, но когда я использую это для того, к чему я действительно стремился:
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";
}
Я получаю ошибку
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";
^
Тогда я понял, что мой has_out_op
требует, чтобы T
был конструируемым по умолчанию, и с тех пор я поворачиваюсь в кругах.Когда у меня есть значение, я могу легко test
, если std::cout << t;
допустим, но только с одним типом я понятия не имею, как правильно реализовать has_out_op
.
Как определить, существует ли соответствующая перегрузка для std::cout << t;
только для данных decltype(t)
?
Обратите внимание, что я уже знаю, как отключить / включить B::operator<<
правильно, но из вежливости я все еще борюсь с правильным has_out_op
.