【发布时间】:2016-06-01 17:19:52
【问题描述】:
由于某些原因,我有一个类必须依赖于 int 模板参数。
出于同样的原因,该参数不能是类的参数列表的一部分,而是其构造函数的参数列表的一部分(当然是模板化的)。
问题出现了。
也许我遗漏了一些东西,但我看不到向构造函数提供这样一个参数的简单方法,因为它不能被推导或明确指定。
到目前为止,我找到了以下替代方案:
将上述参数放入类的参数列表中
创建一个可以调用的工厂方法或工厂函数,例如
factory<42>(params)为构造函数提供一个traits结构
我尝试为最后提到的解决方案创建一个(不是那么)最小的工作示例,也是为了更好地解释问题。
示例中的类本身并不是模板类,关键是构造函数,反正真正的就是模板类。
#include<iostream>
#include<array>
template<int N>
struct traits {
static constexpr int size = N;
};
class C final {
struct B {
virtual ~B() = default;
virtual void foo() = 0;
};
template<int N>
struct D: public B{
void foo() {
using namespace std;
cout << N << endl;
}
std::array<int, N> arr;
};
public:
template<typename T>
explicit C(T) {
b = new D<T::size>{};
}
~C() { delete b; }
void foo() { b->foo(); }
private:
B *b;
};
int main() {
C c{traits<3>{}};
c.foo();
}
说实话,上面提到的解决方案都不适合:
将参数移动到类的参数列表中完全破坏了它的设计,不是一个可行的解决方案
我想避免使用工厂方法,但它可以解决问题
traits struct 似乎是目前为止最好的解决方案,但不知何故我并不完全满意
这个问题很简单:有没有我遗漏的东西,可能是更简单、更优雅的解决方案,我完全忘记的语言细节,或者上面提到的三种方法是我必须选择的? 任何建议将不胜感激。
【问题讨论】:
-
可以推导出来,但是是的,你需要一个标签类型——例如
template<int N> explicit C(traits<N>);(其中traits可以是template<int N> using traits = std::integral_constant<int, N>;) -
是的,这几乎就是我所做的。无论如何,如果我必须引入一个 traits 类,我也可以使用它来定义一些其他的东西,这就是为什么我没有使用像
integral_constant这样的东西。 -
在你的初始段落中,你说它既是模板参数又是构造函数的参数,这没有意义。还是这个矛盾让你感到困惑?
-
我的意思是,如果它很容易推导出来,它将成为构造函数模板声明的参数列表的一部分,如
template<int N> constructor(whatever, you, want)。 -
我不是 100% 清楚你在问什么,但有什么类型的擦除技巧会有所帮助吗?
标签: c++ templates constructor traits software-design