我正在尝试在VC2010下编译以下代码。
struct CircValRange
{
double a,b; // range: [a,b)
};
template <struct CircValRange* Range>
class CircVal
{
// todo
};
const CircValRange SignedDegRange= {-180., 180.};
CircVal<SignedDegRange> x;
我正在
error C2970: 'CircVal' : template parameter 'Range' : 'SignedDegRange' : an expression involving objects with internal linkage cannot be used as a non-type argument
1> d:\4\circval\circval\circval.h(8) : see declaration of 'CircVal'
1> d:\4\circval\circval\circval.h(13) : see declaration of 'SignedDegRange'
我正在尝试定义一个模板化的类CircVal,它将接收一个struct Range作为模板化参数。
我不希望能够将具有一个范围的类分配给具有另一个范围的类(我希望它们是不同的类型)。
我该怎么做?
答案 0 :(得分:6)
有人推荐了一个构造函数参数,我是第二个。但你仍然可以按照原来的要求去做
struct CircValRange
{
double a,b; // range: [a,b)
};
template <CircValRange const& Range>
class CircVal
{
// todo
};
extern const CircValRange SignedDegRange= {-180., 180.};
CircVal<SignedDegRange> x;
但请注意,确定CircVal<SignedDegRange>
的类型标识的属性不是 SignedDegRange
的值,而是地址 / identity它的。也就是说,以下内容不起作用,因为CircVal<SignedDegRange1>
表示不同的类型
extern const CircValRange SignedDegRange1 = {-180., 180.};
CircVal<SignedDegRange1> y = x; // error!
因此,枚举可能更适合此
enum RangeKind {
SignedDegRange,
UnsignedDegRange
};
const CircValRange Ranges[] = { { -180., -180. }, { 0., 360. } };
template <RangeKind Range>
class CircVal
{
// todo
};
甚至是具有静态成员函数的traits类,类似于其他人拥有的解决方案
template <typename Range>
class CircVal
{
// todo
};
struct SignedDegRange {
static double min() { return -180.; }
static double max() { return 180.; }
};
CircVal<SignedDegRange> x;
答案 1 :(得分:4)
为什么不将范围作为构造函数参数?
,而不是将其作为模板?
struct CircValRange
{
double a,b; // range: [a,b)
};
class CircVal
{
public:
CircVal(const CircValRange &_range) : range(_range) {}
private:
CircValRange range;
// todo
};
const CircValRange SignedDegRange= {-180., 180.};
CircVal x(SignedDegRange);
这样,CircVal的每个实例都会有一个相关的范围。然后,您可以覆盖赋值操作符以防止使用不同的值进行赋值。
或者,如果您对模板采用不同的方式感兴趣,可以对范围执行类似的操作:
template <int MIN, int MAX>
class range {
static const int min = MIN, max = MAX;
};
template <class T>
class CircVal {
//todo
};
CircVal< range<10,20> > x;
但当然,这不是很干净或可用。
答案 2 :(得分:1)
template <class Range>
class CircVal
{
// todo
};
或
template <class Range> class CircVal;
template<>
class CircVal<CircValRange> {...
实例化
CircVal<CircValRange> ...
答案 3 :(得分:1)
我认为你省略了一步。如果你想创建一个可以专注于类型的模板CircVal,你可以写:
template<typename Range>
class CircVal
{
...
};
如果您想在CircValRange上专门化它,可以在代码中进一步创建它的实例。
你似乎尝试并强制执行的是它只接受从某个基类派生的类,但不幸的是,这不是模板的工作方式 - 你必须找到另一种强制执行的方法,可能是通过鸭子打字