几分钟前我曾尝试过这样的事情:
#include "stdafx.h"
#include <iostream>
#include <cmath>//for pow
#include <limits>
#include <limits.h>
using std::cout;
template<class T>
struct NumericLimits;
template<>
struct NumericLimits<short>
{
enum :short {max = SHRT_MAX};
};
template<short Mantissa, short Exponent, short Base = 10>
class AllocFactorScientific
{
static_assert(Mantissa > 0,"Mantissa component MUST be > zero");
//why if this works:
static_assert(Mantissa < NumericLimits<short>::max, "Provided number is too large.");
//this doesn't:
static_assert(Mantissa < NumericLimits<decltype(Mantissa)>::max, "Provided number is too large.");
private:
long double factor_;
long double calcFactor_(long int mantissa,long int exponent)
{
return mantissa * ::pow(Base,exponent);
}
public:
AllocFactorScientific():factor_(getFactor()){}
static const long double getFactor()
{
cout << "decltype(Mantissa): " << typeid(decltype(Mantissa)).name() << '\n';
return Mantissa * ::pow(static_cast<double>(Base),Exponent);
}
void setFactor(long int mantissa,long int exponent)
{
factor_ = calcFactor_(mantissa,exponent);
}
};
请参阅代码中的注释(位于类名称下方)
答案 0 :(得分:1)
这只是答案的一半(所以请放心一半),但谷歌提出了一个comp.std.c++线程(由litb发起),其中正在讨论以下代码:
template<int const I>
struct A
{
decltype(I) m;
};
如果decltype
在此上下文中对非类型模板参数合法,我相信它应该是合法的。
答案 1 :(得分:0)
Mantissa
为short
,不需要decltype
。
如果您想要泛型类型,请使用:
template < typename Type, Type Value >
答案 2 :(得分:0)
好吧,我的钱是一个错误。你没有提到你正在使用哪个编译器,但stdafx建议使用各种Visual Studio,我没有。
规范说如果e是实体,则decltype(e)应该具有e的类型。实体是值,对象,引用,函数,枚举器,类型,类成员,模板,模板特化,命名空间,参数包或此。在你的例子中,由于是一个非类模板参数,尾数是一个prvalue,尽管我可以告诉它是一个值,因此是一个实体。因此,根据规范,它似乎应该有效。
我已经在其他两个编译器中尝试了您的代码(包含次要的,无关的修改):CodeGear RAD Studio 2010和g ++ 4.3.4。在RAD Studio中,它无法找到正确的模板:我找不到“max”'。如果我向基础NumericLimits类添加“max”枚举值,static_assert会找到该值并进行比较。
在g ++中,我得到内部编译器错误。
对于它的价值,您可以通过静态变量“清洗”该类型,如下所示:
template<short Mantissa, short Exponent, short Base = 10>
class AllocFactorScientific
{
static decltype(Mantissa) MantissaLaundry;
static_assert(Mantissa > 0,"Mantissa component MUST be > zero");
//why if this works:
static_assert(Mantissa < NumericLimits<short>::max, "Provided number is too large.");
//this works as well now:
static_assert(Mantissa < NumericLimits<decltype(MantissaLaundry)>::max, "Provided number is too large.");
private:
long double factor_;
这似乎适用于RAD Studio,也许它也适用于Visual Studio。或者,您可以缩小问题范围并提交错误报告。