开发者

decltype problem

开发者 https://www.devze.com 2023-01-27 06:07 出处:网络
Few minutes ago I\'ve tried to do something like this: #include \"stdafx.h\" #include <iostream>

Few minutes ago I've tried to do something like this:

 #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开发者_C百科<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);
     }
    };

Please see comments in the code (just below class' name)


This is only half an answer (so feel free to half upvote it), but Google brought up a comp.std.c++ thread (initiated by litb) where the following code is being discussed :

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

If decltype is legal on a non-type template parameter in this context, I believe it should be legal in yours.


Mantissa is short as you declared in the template, there is no need for decltype.

If you want generic types use: template < typename Type, Type Value >


Well, my money is on a bug. You don't mention which compiler you're using, but the stdafx suggests a variety of Visual Studio, which I don't have.

The specification says that decltype(e) should have the type of e if e is an entity. An entity is a value, object, reference, function, enumerator, type, class member, template, template specialization, namespace, parameter pack, or this. In your example, Mantissa is a prvalue by virtue of being a non-class template parameter, which, as near as I can tell is a value and therefore an entity. So, it appears that it should work, according to the spec.

I've tried your code (with minor, irrelevant modifications) in two other compilers: CodeGear RAD Studio 2010 and g++ 4.3.4. In RAD Studio, it fails to find the correct template: I get 'cannot find "max"'. If I add a "max" enum value to the base NumericLimits class, the static_assert finds that value and does a comparison.

In g++, I get internal compiler errors.

For what it's worth, you can 'launder' the type through a static variable like so:

    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_;

This appears to work in RAD Studio, perhaps it will as well in Visual Studio. Alternately, you can narrow down the issue and file a bug report.

0

精彩评论

暂无评论...
验证码 换一张
取 消