decltype问题

时间:2010-11-24 12:40:43

标签: c++ decltype

几分钟前我曾尝试过这样的事情:

 #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);
     }
    };

请参阅代码中的注释(位于类名称下方)

3 个答案:

答案 0 :(得分:1)

这只是答案的一半(所以请放心一半),但谷歌提出了一个comp.std.c++线程(由litb发起),其中正在讨论以下代码:

template<int const I>
struct A
{
   decltype(I) m;
}; 

如果decltype在此上下文中对非类型模板参数合法,我相信它应该是合法的。

答案 1 :(得分:0)

您在模板中声明的<{Mantissashort,不需要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。或者,您可以缩小问题范围并提交错误报告。