 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Frank-René Schäfer Guest
|
Posted: Mon Dec 26, 2005 3:08 pm Post subject: template metaprogramming |
|
|
How can I get a template specilization for type infoa, such as
template <typename T> IsIterator struct { enum { result = false; }
};
template <typename T> IsIterator struct<vector { enum
{ result = true; } };
propperly implemented?
Thanks,
Frank
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Bo Persson Guest
|
Posted: Tue Dec 27, 2005 2:06 am Post subject: Re: template metaprogramming |
|
|
"Frank-René Schäfer" <frank_r_schaefer (AT) gmx (DOT) net> skrev i meddelandet
news:1135603335.300716.173940 (AT) f14g2000cwb (DOT) googlegroups.com...
| Quote: | How can I get a template specilization for type infoa, such as
|
You can't really do that. :-(
| Quote: |
template <typename T> IsIterator struct { enum { result =
false; }
};
template <typename T> IsIterator struct<vector {
enum
{ result = true; } };
propperly implemented?
|
There are two problems here. This specialization is a "non-dedicible
context", which the compiler is not required to resolve. The
difficulty is than for the expression
if (IsIterator<x>::result)
the compiler would have to try out *all* possible values of T, to see
if *any* one of these resulted in an iterator type actually being x.
There just *might* be some type
struct MyType {};
with a specialization
template<>
std::vector<MyType>
{
typedef int* iterator;
// etc.
};
So, any type x, even a pointer, might be an iterator. The compiler
cannot know that, unless it first instantiates vector<T> for all
possible type Ts. And it can't.
Bo Persson
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Frank-René Schäfer Guest
|
Posted: Tue Dec 27, 2005 3:32 pm Post subject: Re: template metaprogramming |
|
|
How would you go for a function that needs to return a reference
to an object, whether it is an object or an interator?
template <typename T>
object_of(&T x) { return x; }
template <typename T>
typename vectro<T>::value_type
object_of(typename vector<T>::iterator& x) { return *x; }
doe not work, for the reason you mentioned.
Regards
Frank
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Vladimir Marko Guest
|
Posted: Tue Dec 27, 2005 3:32 pm Post subject: Re: template metaprogramming |
|
|
Frank-René Schäfer wrote:
| Quote: | How can I get a template specilization for type infoa, such as
template <typename T> IsIterator struct { enum { result = false; }
};
template <typename T> IsIterator struct<vector { enum
{ result = true; } };
propperly implemented?
|
With a decent compiler you might try this approach using the Boost:
// This need not compile. I don't have a compiler at hand right now.
#include "boost/type_traits.hpp"
#include "boost/enable_if.hpp"
struct no { };
struct yes { no no_[2]; };
no IsIteratorHelper(...);
template <typename Iter>
struct IsIterator{
static const bool result =
sizeof(yes)==sizeof( IsIteratorHelper((Iter*)0) );
};
// provide overload for vector<T>::iterator
template <typename Iter>
boost::enable_if<
typename boost::same_type<
Iter,
typename std::vector<
typename std::iterator_traits
| Quote: | ::iterator
::type,
yes
::type IsIteratorHelper(Iter*);
|
The core issue #339 should be resolved before this will truly be
well-formed, but new compilers should accept anyway. I'm pretty
sure that gcc>=3.4 will.
This approach still has one flaw. When providing the IsIteratorHelper
overloads for different containers you must be sure that those
containers really use different iterators. Otherwise the overload
resolution will be ambiguous. This should be reported as an error but
I remember one compiler to wrongly apply SFINAE to ambiguity in
a slightly different context so this might go wrong too.
Cheers,
Vladimir Marko
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Vladimir Marko Guest
|
Posted: Wed Dec 28, 2005 6:12 pm Post subject: Re: template metaprogramming |
|
|
Vladimir Marko wrote:
| Quote: | Frank-René Schäfer wrote:
How can I get a template specilization for type infoa, such as
template <typename T> IsIterator struct { enum { result = false; }
};
template <typename T> IsIterator struct<vector { enum
{ result = true; } };
propperly implemented?
With a decent compiler you might try this approach using the Boost:
// This need not compile. I don't have a compiler at hand right now.
#include "boost/type_traits.hpp"
#include "boost/enable_if.hpp"
struct no { };
struct yes { no no_[2]; };
no IsIteratorHelper(...);
template <typename Iter
struct IsIterator{
static const bool result =
sizeof(yes)==sizeof( IsIteratorHelper((Iter*)0) );
};
// provide overload for vector
template <typename Iter
boost::enable_if
typename boost::same_type
Iter,
typename std::vector
typename std::iterator_traits
::iterator
::type,
yes
::type IsIteratorHelper(Iter*);
|
Or just check if the std::iterator_traits<Iter> can be instantiated,
template <typename Iter>
boost::enable_if<
typename always_true<
typename std::iterator_traits
| Quote: | ::type
::type IsIteratorHelper(Iter*);
|
for a suitable template always_true.
Cheers,
Vladimir Marko
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|