首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >在C++模板中实现条件代码实例化的最简洁方法

在C++模板中实现条件代码实例化的最简洁方法
EN

Stack Overflow用户
提问于 2016-01-04 18:51:17
回答 4查看 4.5K关注 0票数 19

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

#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,在这个模板化的类中,某些操作是根据模板参数来执行的。这些操作需要局部变量,我只想在需要时分配这些变量。我在这里遇到的问题是

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

对于不能编译(使用g++ 5.2)的hasdata=false,条件也是实例化的。你知道如何在不将A::A()的主体分割成碎片的情况下以最干净的方式完成这项工作吗?

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

EN

回答 4

Stack Overflow用户

发布于 2016-01-04 19:09:21

首先,您不需要3个版本的class ConditionalData,因为bool可以是truefalse。因此,让我将其简化为:

template<typename T, bool = false> class ConditionalData {
};                 //^^^^^^^^^^^^

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

其次,为了回答您的问题:无论哪个成员属于false类别,只需在class主体之外重载它们,如下所示:

template<bool hasdata> class A { 
public:
    A() {
        ConditionalData<int,hasdata> data;
        if (hasdata) {
            data.setData(3);
        }
    }   
};

template<> A<false>::A() {}  // Does nothing for `false` condition
票数 5
EN

Stack Overflow用户

发布于 2016-01-04 18:59:16

两个分支都可以定义setDatafalse条件为空:

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

template <typename T> class ConditionalData<T, false> {
    void setData(T _data) {}
};

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<int,hasdata> data;
        data.setData(3);
    }
};
票数 4
EN

Stack Overflow用户

发布于 2016-01-04 19:08:38

如果你不能(/不想)改变ConditionalData,你可以创建两个方法:

template<typename T>
void SetData(ConditionalData<T, false>& , const T& ) {/* Nothing */}

template<typename T>
void SetData(ConditionalData<T, true>& c, const T& value) { c.setData(value); }

然后

A() {
    ConditionalData<int, hasdata> data;
    SetData(data, 3);
}

对于更复杂的情况

template<typename T>
void A_impl_part1(ConditionalData<T, false>&) {/* Nothing */}

template<typename T>
void A_impl_part1(ConditionalData<T, true>& c) { c.setData(3); }

然后

A() {
    ConditionalData<int, hasdata> data;
    A_impl_part1(data);
    // common part
    // A_impl_part2(data); // and so on
}
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34589458

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档