error: functional cast to array type while trying to detect if std::cout << t; is valid
error: functional cast to array type while trying to detect if std::cout << t; is valid
由评论触发 我想写(在 C++11 中)a
template <typename T>
struct has_out_op { static const bool value = ???; }
到 dis/enable 一个成员函数取决于 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
是默认可构造的,从那以后我就在兜圈子。当我有一个值时,如果 std::cout << t;
有效,我可以很容易地 test
,但是仅凭类型我不知道如何正确实现 has_out_op
。
如何检测仅给定 decltype(t)
的 std::cout << t;
是否存在匹配重载?
请注意,我已经知道如何正确 dis/enable B::operator<<
,但出于礼貌,我仍在努力使 has_out_op
正确。
Converts any type T
to a reference type, making it possible to use
member functions in decltype
expressions without the need to go
through constructors.
Note that because no definition exists for declval, it can only be
used in unevaluated contexts; i
...
decltype( test(std::declval<T>(),can_convert_to_base()) )
...
既然我们已经到了这里,您的解决方案就过于复杂了。我会这样做:
struct B {
template <typename T, class = decltype(std::cout << std::declval<T>())>
B& operator<<(const T& t)
{
std::cout << t;
return *this;
}
};
though I would be interested if there is a simpler solution for
has_out_op
template <typename T>
struct has_out_op_impl
{
template <class U, class = decltype(std::cout << std::declval<U>())>
static auto foo(U) -> std::true_type;
static auto foo(...) -> std::false_type;
using Type = decltype(foo(std::declval<T>()));
};
template <class T>
struct has_out_op : has_out_op_impl<T>::Type
{};
struct A{};
int t1()
{
static_assert(has_out_op<int>::value == true, "");
static_assert(has_out_op<A>::value == false, "");
}
由评论触发
template <typename T>
struct has_out_op { static const bool value = ???; }
到 dis/enable 一个成员函数取决于 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
是默认可构造的,从那以后我就在兜圈子。当我有一个值时,如果 std::cout << t;
有效,我可以很容易地 test
,但是仅凭类型我不知道如何正确实现 has_out_op
。
如何检测仅给定 decltype(t)
的 std::cout << t;
是否存在匹配重载?
请注意,我已经知道如何正确 dis/enable B::operator<<
,但出于礼貌,我仍在努力使 has_out_op
正确。
Converts any type
T
to a reference type, making it possible to use member functions indecltype
expressions without the need to go through constructors.Note that because no definition exists for declval, it can only be used in unevaluated contexts; i
...
decltype( test(std::declval<T>(),can_convert_to_base()) )
...
既然我们已经到了这里,您的解决方案就过于复杂了。我会这样做:
struct B {
template <typename T, class = decltype(std::cout << std::declval<T>())>
B& operator<<(const T& t)
{
std::cout << t;
return *this;
}
};
though I would be interested if there is a simpler solution for has_out_op
template <typename T>
struct has_out_op_impl
{
template <class U, class = decltype(std::cout << std::declval<U>())>
static auto foo(U) -> std::true_type;
static auto foo(...) -> std::false_type;
using Type = decltype(foo(std::declval<T>()));
};
template <class T>
struct has_out_op : has_out_op_impl<T>::Type
{};
struct A{};
int t1()
{
static_assert(has_out_op<int>::value == true, "");
static_assert(has_out_op<A>::value == false, "");
}