【问题标题】:How to deduce nesting class template type from typedef composition?如何从 typedef 组合中推断嵌套类模板类型?
【发布时间】:2020-05-31 20:34:05
【问题描述】:

我想从一个 typedef 别名 中为一个专门的类模板定义一个类型。使用相同(但未知)的类模板类型并修改包含的类型。

如何推断别名的类模板类型?

我尝试使用模板模板参数$ clang++ prog.cc -Wall -Wextra -std=c++14 -pedantic

// ----------------------
// third-party header file; may not be modified

template<typename V>
struct UnknownContainer
{
    V m;
};

typedef UnknownContainer<int> KnownAlias;

// ----------------------
// my file (includes third-party header)
// only knows KnownAlias, not UnknownContainer

#include <iostream>
#include <cstdlib>
#include <type_traits>

template< template <typename> class C >
using MakeConstValueType = C< const int >;

typedef MakeConstValueType<KnownAlias> MyContainer;

// example usage

void foo(const MyContainer& c)
{
    std::cout << "value = " << c.m << std::endl;
}

int main()
{
    MyContainer c { 42 };
    foo(c);
}

但我收到此错误:

prog.cc:23:28: error: template argument for template template parameter must be a class template or type alias template
typedef MakeConstValueType<KnownAlias> MyContainer;
                           ^

有什么想法吗?

【问题讨论】:

    标签: c++ templates


    【解决方案1】:

    这是可行的,但您必须评估错误。您编写了一个模板,将另一个模板作为参数接受,但您将其传递给一个具体类型。那是不匹配。模板不是类型,而是创建它们的方法。您可以使用部分模板特化来识别您的元函数何时被赋予从模板生成的类型,但这需要我们使用类模板进行特化。

    总的来说,它可能看起来像这样

    template<class Container, typename NewValT> struct MakeConstValueTypeHelper;
    
    template< template <typename> class C, typename ValueT, typename NewValT>
    struct MakeConstValueTypeHelper<C<ValueT>, NewValT> {
        using type = C<NewValT>;
    };
    
    template< class C >
    using MakeConstValueType = typename MakeConstValueTypeHelper<C, const int>::type;
    

    现在模板参数匹配你打算给它的参数。部分特化将类型展开为其组件,并进行您所追求的转换。

    【讨论】:

    • 非常感谢您的回答!我花了一点时间来理解它。我喜欢部分模板专业化的“技巧”。当applying 您的解决方案时,我删除了NewValT 模板参数,并在type 别名定义中将其替换为std::add_const_t&lt; ValueT &gt;
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-07-26
    • 1970-01-01
    • 2022-12-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多