c++ - 接受常量和非常量数据的通用函数及相关函数

标签 c++ templates c++14

为了使问题标题更有意义,请考虑以下代码:

template <typename T>
void write(const T& /*data*/)
{
    // use data as const
}

template <typename T>
void read(T& /*data*/)
{
    // modify data
}

struct S { 
    int a;
    int b;
    // a lot of primitive types here
};

void output(const S& s)
{
    write(s.a);
    write(s.b);
    // ...
}

void input(S& s)
{
    read(s.a);
    read(s.b);
    // ...
}

int main()
{
    S s;
    input(s);
    output(s);
}

我有 writeread 函数来操作原始数据,如 intdouble 等。我有几个像 S 这样包含大量原始数据成员的结构类型,我需要通过相应的函数 inputoutput 输入和输出这些类型(有许多不同类型的重载)。正如您所看到的,outputinput 函数的内容大部分相同,只是内部函数和类型常量不同。我想制作一些通用(模板)函数 use 来消除 input/output 函数中的代码重复。

我认为模板签名如下(但我可能会漏掉一些东西):

template <typename F, typename T>
void use(T& t) { ... }

所以我可以像这样从input/output调用use函数:

use<write, S>(s); // in output function
use<read, S>(s);  // in input fuction

如何归档此(或类似)行为以消除代码重复?我正在使用 C++14。

最佳答案

template <typename S, typename F>
void use(S&& s, F&& f)
{
    f(s.a);
    f(s.b);
    f(s.c);
}

用法:

use(s, [](const auto& x){ write(x); });
use(s, [](auto& x)      { read(x); });

live example on wandbox.org


如果你需要多种类型:

template <typename S, typename Target>
using EnableFor = std::enable_if_t<std::is_same_v<std::decay_t<S>, Target>>;

template <typename S, typename F>
auto use(S&& s, F&& f) -> EnableFor<S, S0>
{
    f(s.a);
    f(s.b);
    f(s.c);
}

template <typename S, typename F>
auto use(S&& s, F&& f) -> EnableFor<S, S1>
{
    f(s.d);
    f(s.e);
    f(s.f);
}

用法:

int main()
{
    S0 s0; 
    use(s0, [](const auto& x){ write(x); });
    use(s0, [](auto& x)      { read(x); });

    S1 s1;
    use(s1, [](const auto& x){ write(x); });
    use(s1, [](auto& x)      { read(x); });
}

live example on wandbox.org

关于c++ - 接受常量和非常量数据的通用函数及相关函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53833982/

相关文章:

c++ - 使用 utf8 格式的正则表达式过滤字符串

c# - C# 和非托管 native C++ 是否有一种通用方法来确定已安装的 CLR 版本?

C++ - 为任何 lambda 创建实例化桶

当两个线程读取文件并标记 CSV 文件时,c++ Boost 多线程运行缓慢

c++ - 是否可以为 std::any-like 容器转发具有匹配模板类型的函数调用?

c++ - 具有静态存储的变量地址模板

c++ 11 带有 decltype 的尾随返回类型不能按预期工作

c++ - 显式默认模板化构造函数

c++ - 在堆栈上声明固定大小的字符数组 C++

c++ - OpenGL 对象不转换为旋转轴