Вопрос

template<class IntT, IntT low = IntT(), IntT high = IntT()>
struct X 
{
    static_assert(std::is_same<decltype(low),decltype(high)>::value,"Different types not allowed");//this should give error if types are different
    decltype(low) a;
    decltype(high) b;
    X():a(decltype(a)()),b(decltype(b)())//WHY THIS DOES NOT COMPILE?
    {
        cout << typeid(a).name() << '\n';
        cout << typeid(b).name() << '\n';
    }
};

int _tmain(int argc, _TCHAR* argv[])
{


    X<char,1,'a'> x;//this according to static_assert shouldn't compile but it does

    return 0;
}

Using VS2010.
Please see 3 comments in code above.

Это было полезно?

Решение

First thing of note, VS2010 is outdated and was broken the day it was released. The decltype keyword was especially problematic and only works for the most basic of uses. In fact it gets a lot of basic things quite wrong.

Next the code...

template<class IntT, IntT low = IntT(), IntT high = IntT()>
struct X 
{
    static_assert(std::is_same<decltype(low),decltype(high)>::value,"Different types not allowed");//this should give error if types are different

But they never will be.

    decltype(low) a;
    decltype(high) b;

You don't need decltype here. The type is IntT.

    X():a(decltype(a)()),b(decltype(b)())//WHY THIS DOES NOT COMPILE?

Because VS2010 is broken and quite usually won't allow you to use a decltype expression as if it where a type. A typedef before hand might do better.

Luckily you don't need this since you can just use the default constructor rather than the copy.

int _tmain(int argc, _TCHAR* argv[])
{


    X<char,1,'a'> x;//this according to static_assert shouldn't compile but it does

No. The static_assert checks if the types are the same. They are both char with values 1 and 'a'.

    return 0;
}

What you appear to be attempting is to create a template such that the type of the second and third parameters are based on whatever resolved type of the value you pass into it. This can't be done.

Другие советы

The static_assert does compile because the decltype of the template parameters low and high is char. Look at your template definition and the instantiation. IntT <-- char

To default initialize your members you can write this:

X():a(),b()
{
X():a(decltype(a)()),b(decltype(b)())//WHY THIS DOES NOT COMPILE?

GCC compiles it fine. See this : http://www.ideone.com/DG7rt

Looks like it's MSVC++10 compiler bug!

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top