我正在尝试编写一个简单的序列化协议(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/