decltype 的另一个问题
//THIS IS JUST A FRAGMENT OF A static_numeric_limits.h for the purpose of this example
#include <limits.h>
template<class T>
struct static_numeric_limits;
template<>
struct static_numeric_limits<signed char>
{/*min was outside of range for enum*/
static const signed char min = SCHAR_MIN,
max = SCHAR_MAX;
};
/*This "surplus" template is here for the reason that char is threated differently from signed char */
template<>
struct static_numeric_limits<char>
{/*min was outside of range for enum*/
static const char min = SCHAR_MIN,
max = SCHAR_MAX;
};
template<>
struct static_numeric_limits<unsigned char>
{
static const unsigned char min = 0x0,
max = UCHAR_MAX;
};
///REAL PROBLEM STARTS FROM HERE
template<class IntType,IntType low_range = static_numeric_limits<IntType>::min>
struct Int
{
Int():value_(IntType())
{}
Int(const IntType& pattern)
{
value_ = (pattern);
}
constexpr inline IntType getValue()const
{
return value_;
}
private:
IntType value_;
};
template<class IntType,class IntType_1>
auto operator+
(Int<IntType>& lhs, Int<IntType_1>& rhs)
-> Int<decltype(lhs.getValue() + rhs.getValue())>//HERE IS THE PROBLEM
{
return lhs.getValue() + rhs.getValue();
}
错误(来自 VS2010) 错误 C2027:使用未定义类型“static_numeric_limits
错误(来自 gcc 4.6)错误:'decltype ((lhs->getValue() + rhs->getValue()))' 不是模板常量参数的有效类型
为什么这不像我想象的那样工作会吗?
//THIS IS JUST A FRAGMENT OF A static_numeric_limits.h for the purpose of this example
#include <limits.h>
template<class T>
struct static_numeric_limits;
template<>
struct static_numeric_limits<signed char>
{/*min was outside of range for enum*/
static const signed char min = SCHAR_MIN,
max = SCHAR_MAX;
};
/*This "surplus" template is here for the reason that char is threated differently from signed char */
template<>
struct static_numeric_limits<char>
{/*min was outside of range for enum*/
static const char min = SCHAR_MIN,
max = SCHAR_MAX;
};
template<>
struct static_numeric_limits<unsigned char>
{
static const unsigned char min = 0x0,
max = UCHAR_MAX;
};
///REAL PROBLEM STARTS FROM HERE
template<class IntType,IntType low_range = static_numeric_limits<IntType>::min>
struct Int
{
Int():value_(IntType())
{}
Int(const IntType& pattern)
{
value_ = (pattern);
}
constexpr inline IntType getValue()const
{
return value_;
}
private:
IntType value_;
};
template<class IntType,class IntType_1>
auto operator+
(Int<IntType>& lhs, Int<IntType_1>& rhs)
-> Int<decltype(lhs.getValue() + rhs.getValue())>//HERE IS THE PROBLEM
{
return lhs.getValue() + rhs.getValue();
}
Error (from VS2010)error C2027: use of undefined type 'static_numeric_limits<T>'
Error (from gcc 4.6)error: 'decltype ((lhs->getValue() + rhs->getValue()))' is not a valid type for a template constant parameter
Why doesn't this work as I thought it would?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
这里的错误是 decltype 从表达式中推导出来的类型;不幸的是,错误消息并不清楚,这实际上是一个有点棘手的问题。
考虑表达式
0 + 0
的类型。是的,它是一个int
,但更重要的是它是一个右值(非正式地,它是一个临时值)。这意味着decltype(0 + 0)
不是int
,而是int&&
。现在考虑一下您的代码在这方面没有任何不同:您仍然有一个右值。问题是模板非类型参数不能是右值引用,因此由于第二个参数的 type ,您不能使用
Int
。不过,您可以做的是:这会取消
int&&
的引用,为您提供裸露的int
类型。希望 gcc 的错误消息更有意义:它试图告诉您不能将int&&
用于非类型参数。另一个问题(尽管可能不是问题)是整数算术经历所谓的 通常的算术转换。因此,将两个
Int
的值相加的结果实际上是一个int
,因此您的返回类型应该是Int;
(并且是固定代码)。那么,问题是您尚未定义
static_numeric_limits
。但就像我说的,我怀疑这不是问题,你实际上已经定义了它,只是没有显示在你的问题中。The error here is what type
decltype
is deducing from your expression; unfortunately the error messages aren't clear about it, and it's actually a bit of a tricky problem.Consider the type of the expression
0 + 0
. It's anint
, yes, but more importantly it's an rvalue (informally, it's a temporary). This means thatdecltype(0 + 0)
is notint
, butint&&
. Now consider that your code isn't any different, in this regard: you still have an rvalue.The problem is that template non-type parameters cannot be rvalue references, so you cannot have
Int<int&&>
, because of the second parameter's type . What you can do, though is this:This takes the reference off
int&&
, giving you the bareint
type. Hopefully gcc's error message makes a bit more sense: it's trying to tell you that you can't useint&&
for your non-type parameter.Another problem, though probably a non-issue, is that integer arithmetic undergoes what's called the usual arithmetic conversions. So the result of adding the values of two
Int<char>
's is actually going to be anint
, so your return type should beInt<int>
(and is, with the fixed code).The problem, then, is that you haven't defined
static_numeric_limits<int>
. But like I said, I suspect this is a non-issue and you do actually have it defined, just not displayed in your question.