C++0x features in VC2010 – some decltype bugs


1.       decltype(*&function)


https://connect.microsoft.com/VisualStudio/feedback/details/510640


 


int foo();


decltype(*&foo) df; // it should be “int (&)()”, but it is “int (*)()”


 


The internal representation (it is special for “*&function”) doesn’t contain the enough information for decltype to get the correct type.


The work around is to help the compiler:


 


decltype(&foo) temp;


decltype(*temp) df;


 


2.       decltype(*this)


https://connect.microsoft.com/VisualStudio/feedback/details/535484


https://connect.microsoft.com/VisualStudio/feedback/details/535785


 


template<typename T>


auto ObjectTypeHelper(T thisPtr) -> decltype(*thisPtr);


 


class C {


    void f()


    {


        // Crash


        decltype(*this) t1 = *this;


 


        // Workaround 1


        auto t2 = *this;


 


        // Workaround 2


        decltype(ObjectTypeHelper(this)) t3 = *this;


    }


};


 


The crash is caused by the special internal representation of this pointer. So we can work around the bug by using decltype on normal pointer.


 


3.       decltype(const + const)


 


const int i = 0;


const double d = 0;


decltype(i + d) v; // it should be double, but it is const double


 


It is a bug that VC does treat i + d as const double, you can verify that:


 


void f(double &&)


{


}


 


void test()


{


    const int i = 0;


    const double d = 0;


    f(i + d);


}


 


4.       decltype((T &&)o)


 


class B{} b;


 


decltype((B&)b) v1;


decltype((B&&)b) v2; // it should be “B”, but it is “B&”


 


The internal representation for the cast doesn’t contain the enough information for decltype to get the correct type.


 


5.       C++: use of decltype causes premature template instantiation


https://connect.microsoft.com/VisualStudio/feedback/details/548883


 


template<class T> struct C1;


template<class T> struct C2 {};


 


template<class T> C1<T> f();


 


template<class T>


struct C1


{


    decltype(f<C2<T>>()) g();


};


 


template struct C1<int>;


 


The compiler tries to instantiate C1 and enters infinite loop.


However, there is no easy way to work around.


 


6.       C++: when template function argument of array type has size defined via decltype, and it ends up negative, it is replaced with 1


https://connect.microsoft.com/VisualStudio/feedback/details/472511


 


template<class T> struct S {


    static const int size = 1;


};


// Specialization causes the problem


template<> struct S<int> {


    static const int size = -1;


};


 


template<class T> void foo(T t, char (*)[S<decltype(t)>::size])


{


}


 


void test()


{


    foo(0, 0);


}


 


In fact, I think the parameter “t” should not be available in the parameter list. Default argument has this requirement:


 


void f(int x, int y = x) // error C2587: ‘x’ : illegal use of local variable as default parameter


{


}

Comments (0)