Why aren't template expressions simplified internally?

The following example does not work:

#include <iostream>

template <int index, template <typename> class Head,
        template <typename> class... Tail>
struct TemplateTupleElement {
    template <typename T>
    using Type =
            typename TemplateTupleElement<index - 1, Tail...>::template Type<T>;
};

template <template <typename> class Head, template <typename> class... Tail>
struct TemplateTupleElement<0, Head, Tail...> {
    template <typename T>
    using Type = Head<T>;
};

template <typename T>
class Dummy {
};

template <template <typename> class T>
class TemplateDummy {
public:
    static void print() {
        std::cout << "Template" << std::endl;
    }
};

template <>
class TemplateDummy<Dummy> {
public:
    static void print() {
        std::cout << "Specialization" << std::endl;
    }
};

int main(int argc, char* argv[]) {
    TemplateDummy<TemplateTupleElement<0, Dummy, Dummy>::Type>::print();
    TemplateDummy<TemplateTupleElement<1, Dummy, Dummy>::Type>::print();

    return 0;
}

I expected the result would be:

Specialization
Specialization

However, the output of a program compiled with g ++ ((Ubuntu 5.3.0-3ubuntu1 ~ 14.04) 5.3.0 20151204):

Specialization
Template

And exit from Clang (version 3.4-1ubuntu3):

Template
Template

I understand that internally, the compiler presents two template expressions differently:

  • Dummy
  • TemplateTupleElement<1, Dummy, Dummy>::Type

Why is the second expression not “simplified” in the first g ++ expression, and why is Klang not displaying the expression correctly using tuple indices?

+4
source share

No one has answered this question yet.


All Articles