是否有一个模板可以生成类的静态/动态绑定版本
Is there a template that can generate static / dynamically bound versions of a class?
我正在编写一些库代码,我希望用户能够利用静态绑定(如果可以的话)。如果他们无法在编译时实例化一个类,我希望有一个动态版本的类,这样它就可以在运行时实例化。
举个简单的例子,假设我有一个结构模板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_A
和basic_A
以形成完整的A
类:
-
basic_A
在value_A
内部的聚合。这意味着您必须将basic_A
的每个方法路由到value_A
,并在value_A
的两个专业化中提供相应的一行。这可能并没有多大好处,因为您必须复制所有的一行代码,所以请注意。 -
value_A
在basic_A
内部的聚合。您要么也必须将basic_A
作为模板,只需将参数传递给value_A
,并为这两种专门化提供正确的构造函数,可能会通过SFINAE以某种方式禁用和启用它们。也不是一段非常漂亮和可维护的代码。另一种选择是为value_A
的两个专门化创建一个公共基类(Interface),在basic_A
中为该接口创建一个unique_ptr
,并将已构建好的value_A
传递到basic_A
的构造函数中,代价是无论何时您都要访问该值,都要使用虚拟函数调用和poitner间接方法。尤克,尤其是如果A
是一个小型且快速的轻量级。 -
从
value_A
继承basic_A
。与2中的问题相同。apply,关于构造函数和模板参数的转发。 -
从
basic_A
继承value_A
。构造问题消失了,但现在basic_A
不能很容易地访问value_A
的值。一种解决方案是在basic_A
中具有纯虚拟函数getValue()
,value_A
的两个专业化必须实现该函数。这再次带来了虚拟函数调度的成本,这对于小型轻量级类来说可能是不可取的,但它支持封装,因为basic_A
是一个非模板,可以将其实现隐藏在.cpp文件中。另一种方法是在CRTP中使用compiletime多态性,这将使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()
vía 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(); }
};
模板CCD_ 34,又名。4b的CCD_ 35。对于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; }
};
- 在一个解决方案中针对第三方静态库 (Creo) 的不同版本(版本)进行构建
- GCC:--静态链接到pthread的整个存档配方在最近的GCC版本中停止工作
- 用静态版本的QT编译时,文件对话框崩溃
- 拥有相同方法的静态和非静态版本是不是设计不好
- 没有配置文件来制作QT的静态版本
- 如果仅在 lambda 中使用,则不会在发布版本中初始化局部静态变量
- 使用Visual Studio 2013构建QT 5.2.1的静态版本
- G 无法链接共享对象的静态版本
- 静态Qt链接版本,Qt 5.2,QT中的未知模块:快速qml
- 拥有具有相同名称的库的静态和动态版本是一种常见的做法
- 内部在具有不同版本的Visual Studio的静态LIB中使用STL
- C++:将静态类成员与静态类成员的传递版本进行比较
- 两个使用不同libstdc++版本的静态库
- 如何静态链接到两个版本的 xerces-c(或任何与此相关的库)
- C/C++ 尝试创建共享库时出错.创建库的静态版本时不会发生错误
- 如何让编译器在指针上选择模板的静态数组版本
- 使用模板元编程实现 std::all_of 的静态版本
- 是否有一个模板可以生成类的静态/动态绑定版本
- 如何使用Qt的静态构建为Windows创建静态链接版本
- 如何使用代码块为MIGW构建64位版本的Oracle OCI静态库(libocia/w/m.a)