Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Strange behaviour of is_same_template on template aliases

The following program...

#include <iostream>
#include <type_traits>

template <typename T>
struct Template{};

template <typename T>
using Alias = Template<T>;

template
    <
        template <typename>
        class T1,
        template <typename>
        class T2
    >
struct is_same_template : std::false_type{};

template
    <
        template <typename>
        class T
    >
struct is_same_template<T, T> : std::true_type{};

int main() {
    std::cout << std::boolalpha;
    std::cout << "Template == Template: " << is_same_template<Template, Template>::value << std::endl;
    std::cout << "Template == Alias: " << is_same_template<Template, Alias>::value << std::endl;
    std::cout << "Alias == Alias: " << is_same_template<Alias, Alias>::value << std::endl;
}

...outputs...

Template == Template: true
Template == Alias: false
Alias == Alias: true

...compiled with g++ 4.8.1, clang 3.4 and vc++ 18.00.21005.1.

Is it a bug in these compilers or a requirement of the standard?

like image 368
Constructor Avatar asked Oct 21 '22 10:10

Constructor


1 Answers

That is the behavior required by the Standard and it's perfectly logical. A alias template is not a template alias (despite intended by some to be). Initially there appears to have been some confusion even in the Standard about this, see http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1244 .

In the currently Standardized form, an alias template is like its non-templated counter part: It aliases a type. In the template version, the type may be dependent.

And it is immediately substituted. For example Alias<T> with T being itself a template parameter will be the dependent type Template<T> - in this sense the name alias template might be a bit confusing, because it suggests that there will be alias declaration instantiated at some point. But actually the alias pattern is substitued immediately - in this sense the templated version is more like a dependent alias declaration that always exists and does not need to be instantiated, rather than being an alias declaration template.

On that end, it becomes a bit philosophical what precisely we mean with those terms, though.

like image 76
Johannes Schaub - litb Avatar answered Oct 23 '22 09:10

Johannes Schaub - litb