//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)
error C2027: use of undefined type 'static_numeric_limits<T>'
错误(来自gcc 4.6)
error: 'decltype ((lhs->getValue() + rhs->getValue()))' is not a valid type for a template constant parameter
为什么这不能像我想的那样工作?
答案 0 :(得分:1)
此处的错误是decltype
从您的表达式中推断出的类型;不幸的是,错误信息并不清楚,这实际上是一个棘手的问题。
考虑表达式0 + 0
的类型。它是int
,是的,但更重要的是它是 rvalue (非正式地,它是暂时的)。这意味着decltype(0 + 0)
不是int
,而是int&&
。现在考虑你的代码没有任何不同,在这方面:你仍然有一个右值。
问题是模板非类型参数不能是右值引用,因此您不能拥有Int<int&&>
,因为第二个参数的类型。你可以做什么,但是:
#include <type_traits>
// ...
template <class IntType, class IntType_1>
auto operator+(const Int<IntType>& lhs, // be const-correct!
const Int<IntType_1>& rhs)
-> Int<typename std::remove_reference<
decltype(lhs.getValue() + rhs.getValue())>::type>
{
return lhs.getValue() + rhs.getValue();
}
这会将引用关闭int&&
,为您提供裸int
类型。希望gcc的错误信息更有意义:它试图告诉你,你不能使用int&&
作为非类型参数。
另一个问题,虽然可能不是问题,但整数算术会经历所谓的usual arithmetic conversions。因此,添加两个Int<char>
的值的结果实际上将是int
,因此您的返回类型应为Int<int>
(并且使用固定代码)。< / p>
问题是,您尚未定义static_numeric_limits<int>
。但就像我说的那样,我怀疑这是一个非问题,你确实已经定义了它,只是没有显示在你的问题中。