我希望以一种使其调用更简洁的方式实现编译时getter。我有一个非类型(unsigned int N
)类模板foo
,它以递归方式继承自foo<N - 1>
。每个foo
都有自己的名为enum
的{{1}}成员,该成员初始化为其对应的number
的值。基本案例是N
。例如,foo<0>
对象有6个foo<5>
名为enum
,值number
到0
。我想实现一个编译时getter 5
,但它并不像在原型中添加at
那么容易:
constexpr
在g ++ 4.8中,我得到了几个错误实例:template <unsigned int N>
struct foo : protected foo<N - 1> {
protected:
enum {number = N};
public:
constexpr int const& at(const unsigned int index) {
static_assert(index <= N, "out of range");
return this->foo<index>::number;
}
};
template <>
struct foo<0> {
protected:
enum {number = 0};
public:
constexpr int const& at(const unsigned int index) {
static_assert(index == 0, "out of range");
return this->number;
}
};
等等。其他人也跟风。即使所有客户端代码仅使用整数文字调用error: 'index' is not a constant expression
,getter也不会编译。为什么呢?
无论如何,我的解决方案是实现编译时整数包装器。它只是一个非类型(at
)类模板unsigned int N
(编译时int的缩写),其ctint
成员enum
初始化为其mem
:
N
因此,分别用以下内容替换template <unsigned int N>
struct ctint {
enum {mem = N};
};
和foo<N>
的getter方法:
foo<0>
和
template <unsigned int ind>
constexpr int const& at(ctint<ind> const& ctint_par) {
static_assert(ctint_par.mem <= N, "out of range");
return this->foo<ctint_par.mem>::number;
}
工作的:
template <unsigned int ind>
constexpr int const& at(ctint<ind> const& ctint_par) {
static_assert(ctint_par.mem == 0, "out of range");
return this->number;
}
但是使函数调用详细。我想要一个除了部分(例如int main() {
foo<5> f;
static_assert( f.at( ctint<4>{} ) != 4 , "equals 4");
}
)之外没有库的实现,这些部分显示了一些有效但却没有帮助它的工作。我希望getter能够在调用中可选地省略或没有<iostream>
语法或拼写出类型名称,但不一定在原型或定义中。我不希望它涉及<>
。如果这是不可能的,我想知道下一个最佳方式。