Mycroft Holmes
2010-02-25 10:22:01 UTC
Hi all,
we have a large template-based set of headers; they are pretty much
standard compliant and we cross-compile with VS2005, VS2008, the intel
compiler and some versions of gcc. A few days ago we tested VS2010 RC
and we found the following problems:
(1) if a class has swap(T&) and swap(T&&) then in some cases we cannot
take a pointer to swap(T&).
the following sample shows that in ordinary code, the pointer can be
taken, but in a template it can't.
if you remove AAA::swap(AAA&&) it works.
template <typename T>
void fff(T& x, void (T::*)(T&))
{
}
template <typename T>
void fff(T& x)
{
fff(x, &T::swap);
}
struct AAA
{
void swap(AAA&)
{}
void swap(AAA&&)
{}
};
int main()
{
AAA aa;
void (AAA::*F)(AAA&) = &AAA::swap;
fff(aa);
}
(2) sometimes the compiler is unable to fill-it default template
parameters, and it emits...well... bizarre error messages.
in the sample below, if you write "BBB<this_t, roll_t, LENGTH>" it
works, if you write "BBB<this_t, roll_t>" it does not compile.
template <typename r1_t, typename r2_t, int LENGTH1 = r1_t::length,
int LENGTH2 = r2_t::length>
class BBB;
template <typename r1_t, typename r2_t, int LENGTH>
class BBB<r1_t, r2_t, LENGTH, 1>
{
typedef BBB<r1_t, r2_t, LENGTH, 1> this_t;
public:
BBB(int = 0)
{
}
static const int length = LENGTH;
// bug: VS2010 RC will complain if LENGTH is omitted...
// it says that 'length' is undefined
template <typename roll_t>
inline BBB<this_t, roll_t, LENGTH> operator<<(roll_t) const
{
return 0;
}
};
struct E1
{
static const int length = 1;
};
struct E2
{
static const int length = 2;
};
int main(int argc, const char* argv[])
{
BBB<E2, E1> a;
a << E1();
}
(3) we noticed that in error messages, the "template stack" is not
fully unrolled, so most times it's not easy to understand where
exactly the offending code is. e.g. if you have std::pair<void*,
void*>(0,0) instead of (nullptr,nullptr), most times you'll get an
error ONLY in <utility>, not in the original .cpp, as it happens in
VS2008
we have a large template-based set of headers; they are pretty much
standard compliant and we cross-compile with VS2005, VS2008, the intel
compiler and some versions of gcc. A few days ago we tested VS2010 RC
and we found the following problems:
(1) if a class has swap(T&) and swap(T&&) then in some cases we cannot
take a pointer to swap(T&).
the following sample shows that in ordinary code, the pointer can be
taken, but in a template it can't.
if you remove AAA::swap(AAA&&) it works.
template <typename T>
void fff(T& x, void (T::*)(T&))
{
}
template <typename T>
void fff(T& x)
{
fff(x, &T::swap);
}
struct AAA
{
void swap(AAA&)
{}
void swap(AAA&&)
{}
};
int main()
{
AAA aa;
void (AAA::*F)(AAA&) = &AAA::swap;
fff(aa);
}
(2) sometimes the compiler is unable to fill-it default template
parameters, and it emits...well... bizarre error messages.
in the sample below, if you write "BBB<this_t, roll_t, LENGTH>" it
works, if you write "BBB<this_t, roll_t>" it does not compile.
template <typename r1_t, typename r2_t, int LENGTH1 = r1_t::length,
int LENGTH2 = r2_t::length>
class BBB;
template <typename r1_t, typename r2_t, int LENGTH>
class BBB<r1_t, r2_t, LENGTH, 1>
{
typedef BBB<r1_t, r2_t, LENGTH, 1> this_t;
public:
BBB(int = 0)
{
}
static const int length = LENGTH;
// bug: VS2010 RC will complain if LENGTH is omitted...
// it says that 'length' is undefined
template <typename roll_t>
inline BBB<this_t, roll_t, LENGTH> operator<<(roll_t) const
{
return 0;
}
};
struct E1
{
static const int length = 1;
};
struct E2
{
static const int length = 2;
};
int main(int argc, const char* argv[])
{
BBB<E2, E1> a;
a << E1();
}
(3) we noticed that in error messages, the "template stack" is not
fully unrolled, so most times it's not easy to understand where
exactly the offending code is. e.g. if you have std::pair<void*,
void*>(0,0) instead of (nullptr,nullptr), most times you'll get an
error ONLY in <utility>, not in the original .cpp, as it happens in
VS2008