
Ok, first off, this is not explicitly about Boost, which I know is against the Boost guidelines, but I hope you'll all forgive me. Indirectly it is through trying to use Boost that i've bumped into this. A little code snippet... #include <cstddef> template < typename T, std :: size_t sz > struct Block { typedef T type[ sz ][ sz ]; }; template < typename T > void assign( T & assignee, const T & value ); template < typename T, std :: size_t sz > void assign( T ( & assignee )[ sz ], const T ( & value )[ sz ] ); int main( ) { Block< int, 16 > :: type a; const Block< int, 16 > :: type b = { }; assign( a, b ); } This compiles under Gcc & Comeau, but MS VisStudio reckons the call to assign in main is ambiguous. Any thoughts? Also, if I put all the template declarations in an anonymous namespace, Comeau fails to compile, while Gcc is still ok! Have we encountered this before, and is there a known work around? Thanks. - Rob.

Robert Jones wrote:
Ok, first off, this is not explicitly about Boost, which I know is against the Boost guidelines, but I hope you'll all forgive me. Indirectly it is through trying to use Boost that i've bumped into this.
A little code snippet...
#include <cstddef>
template < typename T, std :: size_t sz > struct Block { typedef T type[ sz ][ sz ]; };
template < typename T > void assign( T & assignee, const T & value );
template < typename T, std :: size_t sz > void assign( T ( & assignee )[ sz ], const T ( & value )[ sz ] );
int main( ) { Block< int, 16 > :: type a; const Block< int, 16 > :: type b = { };
assign( a, b ); }
This compiles under Gcc & Comeau, but MS VisStudio reckons the call to assign in main is ambiguous. Any thoughts?
Try comp.lang.c++ - I'd be very interested in the answer.

I've made your problem simpler: #include <cstddef> template < typename T > void assign( T & assignee, const T & value ) {} int main( ) { int a; int const b = 0; assign(a, b); // works. int x[4]; int const y[4] = {}; assign (x,y); // ambiguous T. }

Robert Jones wrote:
Have we encountered this before, and is there a known work around?
No, I have not. However, experimenting with this a bit I found that with both your functions existing an int[] can be passed into assign. Without the second (the T[] version) it cannot...gets the ambiguous T error. If I try to pass an int[][] into assign I get the ambiguous error again. This indicates that it is something about the array type contained within the array that is causing the problem. VS apparently doesn't know how to derive T from T[] when T is an []. It will do it when the second parameter is not const though. This suggests to me that it has something to do with where the const is applied. In int const x[5][5], the int contained within the dual array is the constant. In the case of T const& value[] though it is T that is const, which is an array. This is nonsense I believe (arrays are always r-values). VS seems to have no way to handle it while the others do. I don't know what part of the standard would apply here or who is right. I tried asking in comp.lang.c++ but it's not going to that group I don't think...network here at work isn't always stable. The workaround I'd suggest at this point is to create an assign(T & v[][], T const& [][]). There might also be a more appropriate way to define assign for arrays but I haven't thought of it yet. I imagine this problem has been solved in at least some boost libraries...?

Noah Roberts wrote:
In int const x[5][5], the int contained within the dual array is the constant. In the case of T const& value[] though it is T that is const, which is an array. This is nonsense I believe (arrays are always r-values). VS seems to have no way to handle it while the others do.
I think this is a bug in VS. At first I thought that what I was doing and what you are doing where different because you had a typedef int[size][size] that you later declare a const object of. I thought maybe this actually made the *array* const but I was mistaken. The standard quite clearly states, with example, that even when you are doing that to a typedef of array type...the const applies to the elements, not to the array. The provided example from 8.3.4/1: typedef int A[5], AA[2][3]; typedef const A CA; // type is "array of 5 const int" typedef const AA CAA; // type is "array of 2 array of 3 const int" It doesn't get less ambiguous than that. That means, to me, that even when T is an array type, expecting a const reference of that type should resolve in the same manner and your template should resolve. As someone mentioned in comp.lang.c++ your second version (the one expecting an array) is a closer match and should be the one used. I think there's a bug in msvc in template typing. I'd bet that it's considering const T (&ref)[size] to be an /array of const array of int/ when passed an /array of array of const int/, which is nonsense in C++ and would never resolve to anything.

Hi all, this is what i get from msvc 2008 'void assign(T &,const T &)' : template parameter 'T' is ambiguous 1> : see declaration of 'assign' 1> could be 'const int [4]' 1> or 'int [4]' I hope that this help you. Robert Jones schrieb:
Ok, first off, this is not explicitly about Boost, which I know is against the Boost guidelines, but I hope you'll all forgive me. Indirectly it is through trying to use Boost that i've bumped into this.
A little code snippet...
#include <cstddef>
template < typename T, std :: size_t sz > struct Block { typedef T type[ sz ][ sz ]; };
template < typename T > void assign( T & assignee, const T & value );
template < typename T, std :: size_t sz > void assign( T ( & assignee )[ sz ], const T ( & value )[ sz ] );
int main( ) { Block< int, 16 > :: type a; const Block< int, 16 > :: type b = { };
assign( a, b ); }
This compiles under Gcc & Comeau, but MS VisStudio reckons the call to assign in main is ambiguous. Any thoughts?
Also, if I put all the template declarations in an anonymous namespace, Comeau fails to compile, while Gcc is still ok!
Have we encountered this before, and is there a known work around?
Thanks.
- Rob.
------------------------------------------------------------------------
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
participants (3)
-
Kim Kuen Tang
-
Noah Roberts
-
Robert Jones