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
{
}