C++ 用 SFINAE 重载泛型函数

标签 c++ templates c++17 sfinae

我正在尝试编写一个简单的序列化协议(protocol)。容器类型的 send 应该在每个元素(它们本身可能是容器类型)上调用 send

但是我不知道该怎么做。我已经编写了三个函数,每个函数都单独工作,但我无法弄清楚如何让 C++ 选择和分派(dispatch)适当的函数。我该怎么做?

就目前而言,clang 说我不能用相同的签名重新定义 send(甚至不能为了 SFINAE)。

我正在使用 C++17,但我无法使用诸如 boost 之类的外部库。 [编辑] 这是个人挑战。我想知道如何使用 vanilla C++ 做到这一点。毕竟,该库必须由某人用普通 C++ 编写,对吗? [/编辑]

#include <vector>
#include <utility>
#include <iostream>
#include <type_traits>

template <class pair_t>
std::void_t<typename pair_t::first_type, typename pair_t::second_type>
send(pair_t pair) {
    using first_t = typename pair_t::first_type;
    using second_t = typename pair_t::second_type;

    send<first_t>(std::get<0>(pair));
    send<second_t>(std::get<1>(pair));
}

template <typename list_t>
std::void_t<typename list_t::value_type, typename list_t::size_type>
send(list_t list) {
    using value_t = typename list_t::value_type;

    for (const value_t& elem : list) {
        send<value_t>(elem);
    }
}

template <typename int_t>
void
send(typename std::enable_if<std::is_integral<int_t>::value, int_t>::type val) {
    std::cout << "Sending integral val: " << val << std::endl;
}

int obj0 = 1;
std::vector<int> obj1;
std::pair<int, int> obj2;
std::vector<std::pair<int,int>> obj3;
int main() {
    // send<int>(obj0);
    // send(obj1);
    // send(obj2);
    // send(obj3);
}

最佳答案

你的问题是,就编译器而言,你对 pair 和 list 的声明看起来像:

template <typename T>
blah send(T arg) {
    ...
}

...并且在该签名中没有使用 enable_if。我认为您需要将 enable_if 放入参数类型中。 (我也会通过 const 引用获取 list_t - 你不想不必要地复制列表)。

关于C++ 用 SFINAE 重载泛型函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52585227/

相关文章:

ruby-on-rails - 我应该使用模板来呈现 JSON 还是在 RoR 中使用 Controller 返回 JSON?

c++ - 是否可以使用旧版 C++ 中的 C++ 库?

c++ - 有没有办法在成员名称循环中对 N C++ 类成员应用操作(可能通过预处理器)?

c++ - 传递重载函数指针及其参数时的错误类型推导

c++ - std::any 的存储对象类型的可能性

c++ - 模板函数实现中的条件取决于类型是否为指针

c++ - 如何有效地将底层数据从 std::string 移动到另一种类型的变量?

c++ - 类型和非类型模板特化

c++ - 初始化时的求值顺序

c++ - 如何在 macOS Sierra 上执行图形 C++ 程序