"decay"一个模板别名

3
这是对这个问题的后续说明。
我有一个具有模板模板参数的模板类型。
template <template <typename...> class CONTAINER, typename NUMBERTYPE>
struct spam {
    template <class T>
    using Temp = CONTAINER<T>;
};

我想编写一个(模板)函数,它接受一个 spam 实例并返回一个稍微不同类型的 spam 实例。我想保留输入的 CONTAINER 模板参数,并只指定 NUMBERTYPE。(godbolt 链接
#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返回。非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 Tempstd::vector 相同。实际上,我可以检查到 std::is_same_v<spam<std::vector, float>::template Temp<int>, std::vector<int>> 确实为真——也就是说,在向 Temp 提供模板参数后,我得到了期望/所需的行为,只是我正在贡献代码的部分主要使用未解决的 CONTAINER
问题: 有没有一种方法将 T::template Temp 规范化为任何类型并从类型中删除 spam<...>::Temp

1
虽然这个细节问题对你没有帮助,但是 T::template Temp 不是一个类型,与你最后一句话所说的相反。 - Max Langhof
1个回答

4

问题:有没有一种方法可以将 T::template Temp 规范化为任何东西并从类型中删除 spam<...>::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);
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接