псевдоним типа c ++ не работает при тестировании специализации - PullRequest
0 голосов
/ 25 ноября 2018

Используя 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\n", is_specialization_of<ustruct<int>, ustruct>::value ? "true" : "false" );
    printf( "test u<int> against t, return %s\n", is_specialization_of<ustruct<int>, tstruct>::value ? "true" : "false" );
    printf( "test t<int> against u return %s\n", is_specialization_of<tstruct<int>, ustruct>::value ? "true" : "false" );
    printf( "test t<int> against t, return %s\n", is_specialization_of<tstruct<int>, tstruct>::value ? "true" : "false" );
    getchar();
    return 0;
}

Return:

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 Ответ

0 голосов
/ 25 ноября 2018

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

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

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

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

Если мы рассмотрим ваши тесты с учетом двух вышеупомянутых абзацев, мы увидим, что:

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

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

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

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

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

...