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

{

}