【问题标题】:Using SFINAE to detect existence of a function of void return type使用 SFINAE 检测是否存在返回类型为 void 的函数
【发布时间】:2018-08-02 20:09:46
【问题描述】:

这是我的情况。我正在尝试检测一个类型是否具有 nlohmann::json、namley to_json 使用的特殊方法。现在我已经看到了以下使用 SFINAE 进行免费功能检查的解决方案:

但这些方法至少似乎依赖于函数的 返回类型是否为 void。对于to_json,签名如下:

void to_json(json& j, const T& p);

它返回 void... 从而使这些方法失败(第二个方法实际上不起作用,因为为每种类型定义自定义包装器根本不可行)。

我修改了第一种方法,果然不出所料:

#include <iostream>
#include <type_traits>
#include "json.hpp"

template<class...> struct voider { using type = void; };
template<class... T> using void_t = typename voider<T...>::type;

    template<class T, class = void>
    struct is_jstreamable : std::false_type{};

    template<class T>
    struct is_jstreamable<T, void_t<decltype(to_json(std::declval<nlohmann::json &>(),
                                             std::declval<T>()))>> : std::true_type {};

struct Foo;

template<typename T>
typename std::enable_if<is_jstreamable<T>::value,
        void>::type
bar(){
    std::cout << "It works!" << std::endl;
};

template<typename T>
typename std::enable_if<!is_jstreamable<T>::value,
        void>::type
bar(){
    std::cout << "It doesn't work!" << std::endl;
}

int main(){
//int does have conversion
    bar<int>();
//foo does not have conversion
    bar<Foo>();
}

它无法工作,因为它的 void 类型,控制台返回:

It doesn't work!
It doesn't work!

而不是预期的

It works!
It doesn't work!

我看到了determining if the return of a function is void 的方法,但我不确定如何将其合并为我的问题的解决方案

【问题讨论】:

    标签: c++ templates c++14 metaprogramming sfinae


    【解决方案1】:

    nlohmann::json 有多种方法可以将给定类型转换为 json。没有为int 定义to_json,因此您的类型特征按指定工作。

    相反,检测是否可以将类型转换为nlohmann::json 对象:

    template <typename T>
    using is_jstreamable = std::is_convertible<T, nlohmann::json>;
    

    Live on Godbolt

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-12-08
      • 2015-03-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-11-23
      • 2012-05-29
      相关资源
      最近更新 更多