псевдоним типа c ++ не работает при тестировании специализации

Использование C ++, попытка реализовать: is_specialization_of

template<typename T, template<typename...> class Template>
struct is_specialization_of : std::false_type {};

template<template<typename...> class Template, typename... Tn>
struct is_specialization_of<Template<Tn...>, Template> : std::true_type {};

template<typename... Tn>
struct tstruct {};

template<typename... Tn>
using ustruct = tstruct<Tn...>;

int main( int argc, char **argv )
{
    printf( "test u<int> against u, return %s
", is_specialization_of<ustruct<int>, ustruct>::value ? "true" : "false" );
    printf( "test u<int> against t, return %s
", is_specialization_of<ustruct<int>, tstruct>::value ? "true" : "false" );
    printf( "test t<int> against u return %s
", is_specialization_of<tstruct<int>, ustruct>::value ? "true" : "false" );
    printf( "test t<int> against t, return %s
", is_specialization_of<tstruct<int>, tstruct>::value ? "true" : "false" );
    getchar();
    return 0;
}

Вернуть:

test u<int> against u, return false
test u<int> against t, return true
test t<int> against u return false
test t<int> against t, return true

Похоже, что псевдоним типа не рассматривается как оригинальный тип

Я использую Visual Studio Community 2017

Microsoft (R) C / C ++ Оптимизация компилятора Версия 19.15.26732.1 для x64

Однако при попытке скомпилировать тот же код с помощью gcc он возвращает:

test u<int> against u, return true
test u<int> against t, return true
test t<int> against u return true
test t<int> against t, return true

Есть ли что-нибудь, что я могу сделать для обходного пути?

Всего 1 ответ


Похоже, что псевдоним типа не рассматривается как оригинальный тип, или я что-то пропустил?

Специализация псевдонима - это именно тот тип, который он обозначает. Но псевдоним tempalte - совершенно отличный шаблон . Причина вашего вывода указана в [temp.alias]

1 Объявление шаблона, в котором объявление является объявлением alias, объявляет идентификатор шаблоном псевдонимов. Шаблон псевдонимов - это имя для семейства типов. Имя шаблона псевдонима - это имя шаблона.

2 Когда идентификатор шаблона ссылается на специализацию шаблона псевдонима, он эквивалентен связанному типу, полученному путем подстановки его шаблонных аргументов для параметров шаблона в идентификаторе типа шаблона псевдонима.

Если мы рассмотрим ваши тестовые примеры с учетом вышеуказанных двух пунктов, мы увидим следующее:

  1. "test u<int> против u " - ustruct<int> эквивалентно tstruct<int> указанию tstruct<int> . И tstruct<int> не является специализацией ustruct . Значение должно оцениваться как ложное.

  2. " test u<int> против t " - Здесь ustruct<int> снова эквивалентно tstruct<int> указанию tstruct<int> . И tstruct<int> - это специализация tstruct . Эта черта должна сообщать об этом.

  3. "test t<int> против u " - tstruct<int> не является специализацией ustruct , как мы это ustruct ранее. Эта черта должна сообщать об ошибке.

  4. "test t<int> против t " - Должен сообщать правду.

Все ваши тесты, когда они запускаются в MSVC, соответствуют стандарту C ++, который они должны делать. GCC здесь не соответствует, это ошибка компилятора.


Есть идеи?

10000