"распад" шаблонного псевдонима - PullRequest
3 голосов
/ 06 мая 2019

Это продолжение этого вопроса .

У меня шаблонный тип с аргументом шаблона

template <template <typename...> class CONTAINER, typename NUMBERTYPE>
struct spam {
    template <class T>
    using Temp = CONTAINER<T>;
};

Я хочу написать (шаблонную) функцию, которая принимает экземпляр spam и возвращает экземпляр spam типа слегка другого типа. Я хочу сохранить параметр шаблона CONTAINER из входных данных и указать только NUMBERTYPE. ( Годболт ссылка )

#include <type_traits>
#include <vector>

template <template <typename...> class CONTAINER, typename NUMBERTYPE>
struct spam {
    template <class T>
    using Temp = CONTAINER<T>;
};

template <typename T>
auto function(T in) {
    spam<T::template Temp, double> retval;
    return retval;
}

int main() {
    spam<std::vector, float> one;
    // spam<std::vector, double> two = function(one);
    auto two = function(one);
    return 0;
}

В основном это работает, но я хотел проверить, возвращает ли function() ожидаемый тип, получив ожидаемый spam<std::vector, double> вместо принятия auto. Неавтоматическая версия не компилируется, потому что

<source>:18:45: error: conversion from 'spam<spam<std::vector, float>::Temp,[...]>' to non-scalar type 'spam<std::vector,[...]>' requested

     spam<std::vector, double> two = function(one);

                                     ~~~~~~~~^~~~~

т.е. У меня несоответствие между spam<std::vector, double> и spam<spam<std::vector, float>::template Temp, doulbe>, хотя я ожидаю, что spam<std::vector, float>::template Temp совпадает с std::vector. (Фактически я могу проверить, что std::is_same_v<spam<std::vector, float>::template Temp<int>, std::vector<int>> действительно верно - т.е. после предоставления аргументов шаблона для Temp я ожидал / желал поведения, только то, что код, которому я помогаю, работает в основном с неразрешенным CONTAINER).

ВОПРОС: есть ли способ нормализовать T::template Temp к чему бы то ни было и удалить spam<...>::Temp из типа?

1 Ответ

4 голосов
/ 06 мая 2019

ВОПРОС: есть ли способ нормализовать T :: template Temp к какому-либо значению и удалить спам <...> :: Temp из типа?

Нет,насколько я знаю.

Но в этом нет необходимости, потому что вы можете переписать function(), чтобы перехватить параметр шаблона-шаблона CONTAINER.

Я имею в виду: вы можетепереписать function() следующим образом

template <template <typename...> class C, typename N>
spam<C, double> function (spam<C, N> const &)
 { return {}; }

Ниже приведен полный пример компиляции

#include <type_traits>
#include <vector>

template <template <typename...> class CONTAINER, typename NUMBERTYPE>
struct spam
 {
   template <typename T>
   using Temp = CONTAINER<T>;
 };

template <template <typename...> class C, typename N>
spam<C, double> function (spam<C, N> const &)
 { return {}; }

int main() {
    spam<std::vector, float> one;
    spam<std::vector, double> two = function(one);
    auto three = function(one);
}
...