C++ 模板中条件代码实例化的最简洁方法 [英] Cleanest way for conditional code instantiation in C++ template

查看:26
本文介绍了C++ 模板中条件代码实例化的最简洁方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试运行以下 C++ 代码:

I'm trying to get the following C++ code running:

#include <cmath>

template<typename T, bool> class ConditionalData {
};

template <typename T> class ConditionalData<T, false> {
};

template <typename T> class ConditionalData<T, true> {
private:
    T data;
public:
    void setData(T _data) { data = _data; }
};


template<bool hasdata> class A {
public:
    A() {
        ConditionalData<double,hasdata> data;
        if (hasdata) {
            data.setData(sin(cos(123.4)));
        }
    }
};


int main(int argNum, const char**argData) {
    A<false> test1;
    A<true> test2;
    return 0;
}

本质上,我想实现一个模板化的类 A,其中根据模板参数执行某些操作.这些操作需要局部变量,我只想在需要时分配它们.我在这里遇到的问题是

Essentially, I want to implement a templated class A in which certain operations are executed depending on the template parameter. These operations need local variables, which I only want to be allocated if needed. The problem that I'm having here is that the body of the

if (hasdata) {
    data.setData(3);
}

condition 也为 hasdata=false 实例化,它不会编译(使用 g++ 5.2).任何想法如何以最干净的方式完成这项工作而不将 A::A() 的主体分成几部分?

condition is also instantiated for hasdata=false, which does not compile (using g++ 5.2). Any ideas how to get this done in the cleanest way without splitting the body of A::A() into pieces?

上面的源代码是一个最小的非工作示例.A::A() 的实际实现相对较长,依赖于hasdata"的部分均匀分布在代码中.此外,将使用类 A 的typename T"是一个相对复杂的类,具有重量级的构造函数/析构函数,因此我希望仅在 hasdata=true 时才分配 T 的实例.最后,在 data.setData(...) 调用中,..."中可以有复杂的计算,只有在需要时才应该执行.

The source code above is a minimal non-working example. The real implementation for A::A() is relatively long, with the parts dependent on "hasdata" being distributed evenly over the code. Also, the "typename T" for which the class A will be used is a relatively complex class with heavy-weight constructors/destructors, so I want the instances of T to only be allocated when hasdata=true. Finally, in the data.setData(...) calls, there can be complex computations in the "...", which should only be performed if needed.

推荐答案

如果你能负担得起 ,您可以将条件分支表示为通用 lambda.好处是它们捕获周围的变量,并且解决方案不需要额外的成员函数.

If you can afford for c++14, you can express the conditional branches as generic lambdas. The benefit is that they capture surrounding variables and the solution doesn't require extra member functions.

template <bool> struct tag {};

template <typename T, typename F>
auto static_if(tag<true>, T t, F f) { return t; }

template <typename T, typename F>
auto static_if(tag<false>, T t, F f) { return f; }

template <bool B, typename T, typename F>
auto static_if(T t, F f) { return static_if(tag<B>{}, t, f); }

template <bool B, typename T>
auto static_if(T t) { return static_if(tag<B>{}, t, [](auto&&...){}); }

// ...

ConditionalData<int, hasdata> data;        
static_if<hasdata>([&](auto& d)
{
    d.setData(3);
})(data);

演示

你可以说:

if constexpr (hasdata)
{
    data.setData(3);
}

演示 2

这篇关于C++ 模板中条件代码实例化的最简洁方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆