Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Portable "typeof" of name with external linkage

The Dr.Dobb's article A Portable "typeof" Operator said

But you cannot use a class template to extract a type from an expression, as you can with function templates or overloading. (If the expression is a name with external linkage it is possible to implement typeof with class templates by using a template non-type parameter, but this is not very useful.)

Is the bolded sentence in parentheses correct? And if so how can a template non-type parameter be used to find the type of an expression with external linkage?

like image 630
qbt937 Avatar asked Sep 30 '22 03:09

qbt937


1 Answers

There is no way in C++03 to implement typeof without using sizeof. The closest useful alternative is to extract the type using a function template which returns the desired type.

template<typename T>
struct Type
{
};

template<typename T>
Type<T> makeType(T)
{
    return Type<T>();
}


int main()
{
    int i;

    makeType(2 + 2); // Type<int>
    makeType(&i); // Type<int*>
}

The following technique uses function templates in C++03 to extract the type and value of any expression that can be used in a template argument.

template<typename T, T value>
struct NonType
{
};


template<typename T>
struct Type
{
    template<T value>
    static NonType<T, value>
        makeNonType()
    {
        return NonType<T, value>();
    }
};

template<typename T>
Type<T> makeType(T)
{
    return Type<T>();
}


#define MAKE_NONTYPE(e) makeType(e).makeNonType<e>()

int i;

int main()
{
    MAKE_NONTYPE(2 + 2); // NonType<int, 4>
    MAKE_NONTYPE(&i); // NonType<int*, i>
}

The following answer shows a practical use of this technique to extract the type and value of a pointer to member function expression: How to allow templated functor work on both member and non-member functions

like image 115
willj Avatar answered Oct 03 '22 04:10

willj