C ++ SFINAE运算符/函数结果类型检查

时间:2016-05-24 11:53:23

标签: c++ c++11 sfinae

我正在为Polynomials编写一个基于模板的类。 (评估,多项式之间的一些操作,区分,......),像这样: template <typename _ty> class Polynomial{...

对于to_string函数(以及std::ostream - left-shift-override),我必须检查_ty是否支持< - 运算符(即是对于实数,对于复数,则为no),以便可以很好地格式化字符串。为此我使用此代码:

#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_typetemplate <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,否则返回$query1 = "SELECT username from blog_members INNER JOIN blog_posts ON blog_members.memberID = blog_posts.memberID WHERE blog_posts.memberID = '" .$your_user_id . "';"; 。当然,更通用的解决方案甚至更好。

如果IDE和编译器很重要:我正在使用带有默认设置的Visual Studio 2015。

2 个答案:

答案 0 :(得分:0)

以下是使用fit::is_callable的通用跨平台解决方案,该解决方案最终将添加到Boost中。另请注意C ++ 17中的std::is_callable

无需宏:

list

答案 1 :(得分:0)

您应该重新考虑您的成员方法检测器,并使用最基于 C ++ 11-ish void_t的解决方案。

也就是说,如果我必须更新您的解决方案,可能以下代码是可行的方法:

template <class _op, class _ret, class... _ty>
typename std::enable_if<std::is_same<decltype(std::declval<_op>()(std::declval<_ty>()...)), _ret>::value, std::true_type>::type
impl_test(const _op&, const _ty&...) {
    return std::true_type();
}

这将按照以下方式运作:

struct S { int operator()() { return 42; } };

int main() {
    assert((impl_test<S, int>(S{})));
    // this will give you an error at compile time
    // assert((impl_test<S, double>(S{})));
}