检查函数调用表达式的正确性

Man*_*726 11 c++ sfinae type-traits c++11

std::result_of 在编译时计算调用表达式的返回类型.

正如参考文献所述,如果调用std::result_of格式错误,则会导致编译错误.但是假设我们需要的是在获得结果类型之前检查调用是否格式正确.

有没有办法写一个特征来检查调用表达式是否格式正确?

就像是:

template<typename F , typename... ARGS>
struct is_valid_call : public impl::is_valid_call<F,typelist<ARGS...>>
{};

namespace impl
{
    struct sfinae_result{};

    template<typename F , typename ARGS , typename ENABLED = sfinae_result>
    struct is_valid_call;

    template<typename F , typename... ARGS>
    struct is_valid_call<F,typelist<ARGS...>,
                         decltype( std::declval<F>()(std::declval<ARGS>()...) )
                        > : 
        public std::true_type
    {};

    template<typename F , typename... ARGS>
    struct is_valid_call<F,typelist<ARGS...>,sfinae_result> : 
        public std::false_type
    {};
}
Run Code Online (Sandbox Code Playgroud)

编辑:当然,发布的解决方案不起作用

jro*_*rok 7

这是有效的:

#include <type_traits>
#include <utility>

template<typename F, typename... Args>
struct is_valid_call {
private:
    template<typename FF, typename... AA>
    static constexpr auto check(int) ->
    decltype( std::declval<FF>()(std::declval<AA>()...), std::true_type());

    template<typename FF, typename... AA>
    static constexpr std::false_type check(...);
public:
    static constexpr bool value = decltype(check<F, Args...>(0)){};
};

#include <cstdio>

int main()
{
   printf("%d", int (is_valid_call<decltype(&puts), const char*>::value));
   printf("%d", int (is_valid_call<decltype(&puts), double>::value));
}
Run Code Online (Sandbox Code Playgroud)

输出: 10

  • 这可能是你被咬过的东西 - 你的实现不起作用,因为`impl :: is_valid_call`的第二个专业化更专业,总是被选中.它认为,至少 - 这是星期天晚上的晚上,我的脑袋已经不再那么清楚......我也不明白为什么你会失望 - 这是你的好表达SFINAE. (2认同)
  • +1尼斯解决方案.一个密切相关(和有用)的特性是我称之为"invokable".它允许所有5个子弹从20.9.2/p1(`is_valid_call`只允许第5个子弹).这个扩展的特性包括(例如)可以构造`std :: thread`或`std :: function`的参数,包括指向成员函数的指针和指向成员数据的指针.Imho足够具有挑战性和有用性以保证标准化. (2认同)