我正在为多项式编写一个基于模板的类。 (评估,多项式之间的一些操作,微分,......),就像这样:
template <typename _ty> class Polynomial{...
对于 to_string
函数(和 std::ostream
-left-shift-override),我必须检查,如果 _ty
支持<
- 运算符(即对于实数是,对于复数不是),以便可以很好地格式化字符串。为此,我使用此代码:
#include <type_traits>
template <class _op, class... _ty, typename = decltype(std::declval<_op>()(std::declval<_ty>()...))>
std::true_type impl_test(const _op&, const _ty&...) { return std::true_type(); }
std::false_type impl_test(...) { return std::false_type(); }
template <class> struct supports;
template <class _op, class... _ty> struct supports<_op(_ty...)> : decltype(impl_test(std::declval<_op>(), std::declval<_ty>()...)){};
#define is_ineq_supported(type) supports<std::less<>(type, type)>()
简而言之,is_ineq_supported(type)
返回 std::true_type
如果 <
存在有效的重载-运算符,和一个 false_type
如果不。然后可以使用 true_type
调用相应的函数。或 false_type
作为区分论点,像这样:
template <typename _ty> void do_stuff(_ty arg, const std::true_type&) {
// do stuff with the '<'-operator
}
template <typename _ty> void do_stuff(_ty arg, const std::false_type&) {
// do stuff without the '<'-operator
}
template <typename _ty> void do_stuff(_ty arg) {
do_stuff(arg, is_ineq_supported(_ty));
}
我还有一个 Vector 类,它重载了二进制 *
-运算符与点积,所以它返回一个 double
.但对于多项式,只有系数和参数在相互相乘时返回相同类型才有意义。
我的问题如下: 我想要一种检查给定操作是否返回指定类型的方法。 (也许是类似的宏?)我认为,最简单的是返回 true_type
的东西如果结果类型匹配参数类型和 false_type
否则。当然,更通用的解决方案更好。
以防万一,IDE 和编译器很重要:我使用的是默认设置的 Visual Studio 2015。
最佳答案
这是一个通用的跨平台解决方案,使用 fit::is_callable
,最终将添加到 Boost.还要留意 std::is_callable
在 C++17 中。
不需要宏:
#include <type_traits>
#include <iostream>
#include <fit/is_callable.hpp>
// std::less doesn't SFINAE, so we make our own test
struct less_test {
template<typename L, typename R>
auto operator()(L l, R r) -> decltype(l < r);
};
template<typename T>
using is_less_than_comparable = fit::is_callable<less_test, T, T>;
// operator< version (replace with your implementation)
template <typename T> constexpr auto
do_stuff(T arg, const std::true_type&) {
return std::integral_constant<int, 0>{};
}
// other version (replace with your implementation)
template <typename T> constexpr auto
do_stuff(T arg, const std::false_type&) {
return std::integral_constant<int, 1>{};
}
template <typename T> constexpr auto
do_stuff(T arg) {
return do_stuff(arg, is_less_than_comparable<T>{});
}
struct foo {};
int main() {
//is not less-than comparable
static_assert(do_stuff(foo{}) == 1, "");
//is less-than comparable
static_assert(do_stuff(0) == 0, "");
}
关于C++ SFINAE 运算符/函数结果类型检查,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37412781/