Topic: Member name as template parameter


Author: Nikolay Ivchenkov <tsoae@mail.ru>
Date: Fri, 9 Oct 2009 16:50:58 CST
Raw View
Is there a proposal to add new kind of template parameters - name
aliases? It is impossible to specify member name in C++03 and in C++0x
as template argument. For a generic code that accepts member name we
have to use macro instead of template - like offsetof. For example, we
can define macro that determines whether a specified nested type is
present in the given type:

#include <iostream>

#define DEF_NESTED_TYPE(NestedType) \
template <class T> \
     struct ClassNestedType##NestedType \
{ \
private: \
     typedef char Case_1[1]; \
     typedef char Case_2[2]; \
     template <class> \
         struct Param; \
     template <class Tx> \
         static Case_1 &check(...); \
     template <class C> \
         static Case_2 &check( \
             Param<typename C::NestedType> *); \
public: \
     enum \
     { \
         exists = \
             sizeof check<T>(0) == \
             sizeof(Case_2) \
     }; \
};

#define HAS_NESTED_TYPE(T, NestedType) \
     ClassNestedType##NestedType<T>::exists

struct X
{
     typedef int Nested;
};

DEF_NESTED_TYPE(Nested)
DEF_NESTED_TYPE(Other)

int main()
{
     std::cout
         << HAS_NESTED_TYPE(X, Nested)
         << std::endl
         << HAS_NESTED_TYPE(X, Other)
         << std::endl;
}

The following pseudo-code shows potentially possible solution with
template:

template <class T, virtual NestedType>
     struct HasNestedType
{
private:
     typedef char Case_1[1];
     typedef char Case_2[2];
     template <class>
         struct Param;
     template <class Tx>
         static Case_1 &check(...);
     template <class C>
         static Case_2 &check(
             Param<typename C::|NestedType> *);
public:
     enum
     {
         value =
             sizeof check<T>(0) ==
             sizeof(Case_2)
     };
};

struct X
{
     typedef int Nested;
};

int main()
{
     std::cout
         << HasNestedType<X, |Nested>::value
         << std::endl
         << HasNestedType<X, |Other>::value
         << std::endl;
}

Name aliases in template parameters can also allow to bind overloaded
functions, function templates, and functions with default arguments
very well. Pointers to members don't provide such flexibility.

--
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]