"decay" 一个模板化的别名

"decay" a templated alias

这是 this question 的跟进。

我有一个带有模板模板参数的模板化类型

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

我想编写一个(模板化的)函数,它接受一个 spam 实例和 returns 一个 稍微 不同的 spam 实例类型。我想维护输入中的 CONTAINER 模板参数并仅指定 NUMBERTYPE。 (godbolt link)

#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;
}

这大部分都有效,但我想通过接收预期的 spam<std::vector, double> 而不是接受 auto [= 来检查 function() return 是否是我预期的类型47=]。非自动版本无法编译,因为

<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 Tempstd::vector 相同。 (事实上​​我可以检查 std::is_same_v<spam<std::vector, float>::template Temp<int>, std::vector<int>> 确实是真的 - 即在向 Temp 提供模板参数后我有 expected/desired 行为,只是我贡献的代码主要与未解决 CONTAINER).

问题:有没有办法将 T::template Temp 规范化为任何类型并从类型中删除 spam<...>::Temp

QUESTION: is there a way to normalize T::template Temp to whatever it is and remove the spam<...>::Temp from the type?

没有,据我所知

但在这种情况下没有必要,因为您可以重写 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);
}