【问题标题】:Can I specialize an variadic template template parameter with non template class?我可以用非模板类专门化可变参数模板模板参数吗?
【发布时间】:2016-03-23 22:23:57
【问题描述】:

我想通过非模板类专门化一个带有可变模板模板参数的模板类。请看下文。

// non-template base class
class BaseNoneTemplate {
public:
    void print(void) {
        std::cout << "BaseNoneTemplate" << std::endl;
    }
};

// template base class
template <typename T>
class BaseTemplate {
public:
    void print(void) {
    std::cout << "BaseTemplate" << std::endl;
    }
};

// primary template class
template <template <typename...> class T_Self, typename... T_Params>
class VariadicTemplate : public T_Self<T_Params...> {
public:

    VariadicTemplate() = default;
    virtual ~VariadicTemplate() = default;

    void print(void) {
        this->T_Self<T_Params...>::print();
    }

};

// specialized class with a non-template class
// ********** This specialized class makes an error: see the error message at the end of this question ***********
template <>
class VariadicTemplate<BaseNoneTemplate> : public BaseNoneTemplate {
public:

    VariadicTemplate() = default;
    virtual ~VariadicTemplate() = default;

    void print(void) {
        this->BaseNoneTemplate::print();
    }

};

// specialized class with an template class
// ***** This class is an ok example *****
template <typename T_Value>
class VariadicTemplate<BaseTemplate, T_Value> : public BaseTemplate<T_Value> {
public:

    VariadicTemplate() = default;
    virtual ~VariadicTemplate() = default;

    void print(void) {
        this->BaseTemplate<T_Value>::print();
    }

};

void test_variadic_template(void) {
    VariadicTemplate<BaseNoneTemplate> non_template;
    VariadicTemplate<BaseTemplate, int> an_template;
    non_template.print();
    an_template.print();
}

在上面的代码中,我无法通过非模板类 BaseNoneTemplate 专门化具有可变模板模板参数的模板类。 有人知道如何使用非模板类对其进行专门化吗?

编译器的错误如下,

../template_template_variadic.hpp:44:40: error: type/value mismatch at argument 1 in template parameter list for ‘template<template<class ...> class T_Self, class ... T_Params> class VariadicTemplate’ class VariadicTemplate<BaseNoneTemplate> : public BaseNoneTemplate {
                                    ^
../template_template_variadic.hpp:44:40: note:   expected a class template, got ‘BaseNoneTemplate’

非常感谢。

【问题讨论】:

    标签: c++ templates


    【解决方案1】:

    再增加一层泛化怎么样?

    //...
    template <typename... Types>
    class VariadicTemplate;
    
    // primary template class
    template <template <typename...> class T_Self, typename... T_Params>
    class VariadicTemplate<T_Self<T_Params...>, T_Params...>: public T_Self<T_Params...> {
    //...
    };
    
    //...
    void test_variadic_template(void) {
        VariadicTemplate<BaseNoneTemplate> non_template;
        VariadicTemplate<BaseTemplate<int>, int> an_template;
        non_template.print();
        an_template.print();
    }
    

    我删除了我没有更改的部分。此代码无法在 MSVC2015 上编译,但原因未知。我已经提交了bug,但如果您正在使用它,那么它不会很快为您提供帮助。


    此版本适用于 MSVC(除了更简洁干净之外):

    template <typename... Types>
    class VariadicTemplate;
    //..
    template <template <typename...> class T_Self, typename... T_Params>
    class VariadicTemplate<T_Self<T_Params...>>: public T_Self<T_Params...> {
    //...
    }
    //...
    void test_variadic_template(void) {
        VariadicTemplate<BaseNoneTemplate> non_template;
        VariadicTemplate<BaseTemplate<int>> an_template;
        non_template.print();
        an_template.print();
    }
    

    【讨论】:

    • 谢谢你,ixSci 给我答案。
    • 嗨,ixSci。我之前推过它,它变成了绿色。但是,您可能不会接受它。我再推一下。可以吗?或者我如何检查它是否正常工作?
    【解决方案2】:

    如果您的 VariadicTemplate 期望 template &lt;typename...&gt; class, typename... 作为模板参数,则您不能将其专门用于 type

    您可以做的是期望 type 并专门针对特定类型或(部分)专门针对来自模板类型的类型。

    template <typename T> class VariadicTemplate;
    
    // Partial specialization
    template <template <typename...> class C, typename... Ts>
    class VariadicTemplate<C<Ts...>> : public C<Ts...> {
    public:
        void print() { C<Ts...>::print(); };
        // or using C<Ts...>::print;
    };
    
    // Full specialization
    template <>
    class VariadicTemplate<BaseNoneTemplate> : public BaseNoneTemplate {
    public:
        void print() { BaseNoneTemplate::print(); };
        // or using BaseNoneTemplate::print;
    };
    

    Demo

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-07-31
    • 2023-03-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-16
    相关资源
    最近更新 更多