gpt4 book ai didi

c++ - 是否有可以生成类的静态/动态绑定(bind)版本的模板?

转载 作者:太空狗 更新时间:2023-10-29 21:19:33 25 4
gpt4 key购买 nike

我正在编写一些库代码,我希望用户能够在可能的情况下利用静态绑定(bind)。如果他们无法在编译时实例化一个类,我希望有一个类的动态版本,以便它可以在运行时实例化。

举个简单的例子,假设我有一个结构模板 A:

template<bool dynamic, int value=0> struct A
{
static const int Value = value;
};


template<> struct A<true>
{
int Value;
A(int value) : Value(value) {}
};

这些定义允许库的用户静态和动态地实例化 A:

A<true> dynamicA = A<true>(5);

A<false, 5> staticA;

这个方法的问题是我必须写两次类的定义。我可以想出几种实现自己生成两个版本的模板的方法,但我可以看到它会变成很多工作。特别是对于使用不同数量参数的类,例如:

// It would be much harder to generate a static version of this class, 
// though it is possible with type lists. Also, the way I'm imagining it,
// the resulting classes probably wouldn't be very easy to use.
struct A
{
vector<int> Values;
A(vector<int> value) : Values(value) {}
};

这个模式/问题有名字吗?是否有一个元编程库具有可以为我生成两个定义的模板?我如何避免必须两次编写我的类的定义?

最佳答案

有一种简单的机制可以将不依赖于动态/静态值问题的部分放到一个位置:将它们放到另一个类中,我们称之为basic_A,我们称之为您在问题 value_A 中显示的静态/动态值容器。 value_Abasic_A 有不同的连接方式,可以组成完整的 A 类:

  1. value_A 内聚合 basic_A。这意味着您必须通过 value_A 路由 basic_A 的每个方法,并在 value_A 的两个特化中提供相应的单行代码。这可能不会有太大收获,因为您必须复制所有单行代码,所以从头开始。

  2. basic_A 内聚合 value_A。您也必须将 basic_A 设为模板,仅将参数传递给 value_A 并为两个特化提供正确的构造函数,可能以某种方式通过 SFINAE 禁用和启用它们.也不是一段非常漂亮和可维护的代码。另一种方法是为 value_A 的两个特化创建一个公共(public)基类(接口(interface)),在 basic_A 中为该接口(interface)设置一个 unique_ptr 并且将准备好的构造 value_A 传递给 basic_A 的构造函数,只要您想要访问该值,就会以虚函数调用和 poitner 间接寻址为代价。糟糕,特别是如果 A 是一个小而快的轻量级类。

  3. value_A 继承 basic_A。与 2. 中相同的问题适用,关于构造函数和模板参数的转发。

  4. basic_A 继承 value_A。构造问题消失了,但是现在 basic_A 不能轻易访问 value_A 的值。一种解决方案是在 basic_A 中有一个纯虚函数 getValue()value_A 的两个特化必须实现。这再次具有虚函数调度的成本,这对于小型轻量级类来说可能是不可取的,但它启用了封装,因为 basic_A 是一个非模板并且可以将其实现隐藏在 .cpp 文件中.另一种方法是通过 CRTP 使用编译时多态性,这将使 basic_A 再次成为模板。

下面是4.的两种方法的两个例子:

4a: getValue() 作为虚函数:

//basic_a.hpp

struct basic_A {
int foo() const;
virtual int getValue() const = 0;
};

//basic_A.cpp
int basic_A::foo() const { return 10 * getValue(); }

4b: getValue() 通过 CRTP

template <class Value_t>
struct basic_A {
int foo() const { return 10 * value_(); }
private:
int value_() const { return static_cast<Value_t const&>(*this).getValue(); }
};

模板 A 又名。 4b 的 A_value 如下。对于 4a,它几乎是一样的,只是去掉 basic_A 中的模板参数和括号,因为它是一个普通类:

template <bool dyn, int value = 0> 
struct A;

template <>
struct A<true, 0> : basic_A<A<true, 0>>
{
int val;
int getValue() const { return val; }
};

template <int value>
struct A<false, value> : basic_A<A<false,value>>
{
int geValue() { return value; }
};

关于c++ - 是否有可以生成类的静态/动态绑定(bind)版本的模板?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26888745/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com