[non Boost] Template troubles.

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, On Wed, Dec 10, 2008 at 9:29 AM, Robert Jones <robertgbjones@gmail.com>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.
I'm sure no-one will mind much given that you have contributed so nicely to this list in the past.
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 ] );
Neither of these are exact matches... is this deliberate? Or did you mean: template<typename T, std::size_t sz> void assign(T (&assignee)[sz][sz], const T(&value)[sz][sz]) { } I wondered this, because this modification makes it compile on Visual C++ because it is an exact match.
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!
That would have to be a problem with Comeau because the introduction of an anonymous namespace for all of the functions (if they remain in the same translation unit) should not make a difference to the best of my knowledge an belief.
Have we encountered this before, and is there a known work around?
Thanks.
- Rob.
I hope this helps, Neil
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

On Wed, Dec 10, 2008 at 10:20 AM, Neil Groves <neil@grovescomputing.com>wrote:
Neither of these are exact matches... is this deliberate? Or did you mean:
template<typename T, std::size_t sz> void assign(T (&assignee)[sz][sz], const T(&value)[sz][sz]) { }
I wondered this, because this modification makes it compile on Visual C++ because it is an exact match.
Hi Neil Ultimately the signature you suggest is what I want to call, however I was hoping to achieve this via recursive instantiation, largely because looping over one index in the implementation is easily achieved with a for_each loop and a bind() call, whereas looping over two indices is rather cumbersome. In practise there's also some other house keeping, which makes the recursive instantiation approach quite attractive. The exact match case you present is spot on, and in fact was my first cut at this functionality. What I'm unclear on is why the single dimensional case is not also an exact match with appropriate inferring of T. Thanks for your thoughts. - Rob.

Robert, On Wed, Dec 10, 2008 at 10:55 AM, Robert Jones <robertgbjones@gmail.com>wrote:
On Wed, Dec 10, 2008 at 10:20 AM, Neil Groves <neil@grovescomputing.com
wrote:
Neither of these are exact matches... is this deliberate? Or did you
mean:
template<typename T, std::size_t sz> void assign(T (&assignee)[sz][sz], const T(&value)[sz][sz]) { }
I wondered this, because this modification makes it compile on Visual C++ because it is an exact match.
Hi Neil
Ultimately the signature you suggest is what I want to call, however I was hoping to achieve this via recursive instantiation, largely because looping over one index in the implementation is easily achieved with a for_each loop and a bind() call, whereas looping over two indices is rather cumbersome. In practise there's also some other house keeping, which makes the recursive instantiation approach quite attractive.
I now understand the motivation, however I think you are out of luck unless you disambiguate the calls. Perhaps you can use SFINAE, or dare I suggest using boost::array<boost::array< constructions instead?
The exact match case you present is spot on, and in fact was my first cut at this functionality. What I'm unclear on is why the single dimensional case is not also an exact match with appropriate inferring of T.
Thanks for your thoughts.
- Rob.
Neil
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Robert Jones wrote:
On Wed, Dec 10, 2008 at 10:20 AM, Neil Groves <neil@grovescomputing.com>wrote:
Neither of these are exact matches... is this deliberate? Or did you mean:
template<typename T, std::size_t sz> void assign(T (&assignee)[sz][sz], const T(&value)[sz][sz]) { }
I wondered this, because this modification makes it compile on Visual C++ because it is an exact match.
Hi Neil
Ultimately the signature you suggest is what I want to call, however I was hoping to achieve this via recursive instantiation, largely because looping over one index in the implementation is easily achieved with a for_each loop and a bind() call, whereas looping over two indices is rather cumbersome.
Didn't realize you'd also asked here (should pay more attention to destinations). I think I gave you an idea why this is happening in my response. As to doing it recursively: template < typename T, size_t s > void assign(T (&dest)[s][s], const T (&orig)[s][s]) { for (size_t i = 0; i < s; ++i) assign(dest[i], orig[i]); } should work... untested. As to extending this to arbitrary depth of arrays...you'll probably need to use the boost preproc lib. I don't think even variadic templates would help you here (and certainly wouldn't make it compile better in VS). Note: adjusted the destinations so that everyone that's heard the question has now heard the answers.
participants (3)
-
Neil Groves
-
Noah Roberts
-
Robert Jones