Thread overview | ||||||
---|---|---|---|---|---|---|
|
August 15, 2004 [Bug report] Bugs affecting boost::is_convertible | ||||
---|---|---|---|---|
| ||||
Hi, I've been trying to get boost::is_convertible to work, and my version almost always does. But there are a few problems. The first one is a bit odd. In the following test case, if the commented out line is uncommented the program fails on the second function call. I believe that the compiler is reusing the instantiated template test<int[2]> when it instantiates test<const int[2]> which gives test<const int[2]>::func a non-const argument type. This causes a lot of the unit tests for the boost type_traits to fail. template<class T> struct test { static void func(T x) {} }; int main() { int x[2] = {1, 2}; //test<int[2]>::func(x); const int x2[2] = {1, 2}; test<const int[2]>::func(x2); } Secondly, void* shouldn't be implicitly convertible to other pointer types, and non-const references shouldn't be initialised from temporaries (the compiler warns about that, but it should be an error). Here are the test cases: int main() { int x; char& x2 = x; // This should fail, there is currently a warning } and: int main() { void* y; int* y2 = y; // This should fail } Finally, in the following example the compiler gives a link error because it can't find test::from, but as from is only referred to from the 'sizeof' it shouldn't be linked to. (In boost::is_convertible this is actually in a template, such that 'from' won't have a default constructor, which is why an instance of it can't be defined). I've actually got a work around for this one, but it's a little nasty, so it would be nice if this was fixed. struct test { static char from; }; int check(int const&); const int value = sizeof(check(test::from)); int main(){ } thanks, Daniel |
August 16, 2004 Re: [Bug report] Bugs affecting boost::is_convertible | ||||
---|---|---|---|---|
| ||||
Posted in reply to Daniel James | "Daniel James" <daniel@calamity.org.uk> wrote in message news:411FC75F.9050804@calamity.org.uk... > The first one is a bit odd. In the following test case, if the commented out line is uncommented the program fails on the second function call. I believe that the compiler is reusing the instantiated template test<int[2]> when it instantiates test<const int[2]> which gives test<const int[2]>::func a non-const argument type. This causes a lot of the unit tests for the boost type_traits to fail. > > template<class T> > struct test > { > static void func(T x) {} > }; > > int main() > { > int x[2] = {1, 2}; > //test<int[2]>::func(x); > > const int x2[2] = {1, 2}; > test<const int[2]>::func(x2); > } I've had a lot of trouble with const, as sometimes it means a different type and sometimes it doesn't. Are you sure it really means a different template should be instantiated here? |
August 16, 2004 Re: [Bug report] Bugs affecting boost::is_convertible | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter | Walter wrote:
> I've had a lot of trouble with const, as sometimes it means a different type
> and sometimes it doesn't. Are you sure it really means a different template
> should be instantiated here?
Well, I'm not 100% sure, I'm not a languague lawyer. The fact that the
first instantiation breaks the second seems to suggest that it should,
and the other compilers I've tried have no problems with this.
Having said that, it's not a big problem. As far as type_traits are concerned, it may cause some of the tests to fail, but it's unlikely to cause a problem in normal use. I'm sure you've got a lot of far more important things to worry about.
thanks,
Daniel
|
August 16, 2004 Re: [Bug report] Bugs affecting boost::is_convertible | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter | It looks like there's the same problem with const void. Personally, I'm surprised that you can have a const void. Here's a simple test: template <class T> struct add_pointer { typedef T* type; }; int main() { void* x; add_pointer<void>::type x1 = x; const void* y; add_pointer<const void>::type y1 = y; } Here's a longer, but more realistic, test: template <typename T> struct is_const_impl {}; template <typename T> struct is_const_impl<T*> { static const bool value = false; }; template <typename T> struct is_const_impl<const T*> { static const bool value = true; }; template <typename T> struct is_const { static const bool value = is_const_impl<T*>::value; }; #define STATIC_ASSERT(name, x) \ typedef char name[(x) ? 1 : -1]; STATIC_ASSERT(test_const_void, is_const<const void>::value); STATIC_ASSERT(test_void, !is_const<void>::value); STATIC_ASSERT(test_const_array, is_const<const int[2]>::value); STATIC_ASSERT(test_array, !is_const<int[2]>::value); Volatile acts in a similar manner. But, as I said before, this is unlikely to cause problems in normal use. Daniel |
Copyright © 1999-2021 by the D Language Foundation