具有可变参数专业化的模板函数

问题描述 投票:0回答:1

是否有可能以某种方式进行模板函数专门化,如下所示:

template<typename T, typename... Args>
void Func(size_t id, Args... args) { std::cout << "1\n" }

template<>
void Func<SomeClass>(size_t id, Args... args) { std::cout << "2\n" }

所以我想保留可变参数,但指定 T = SomeClass:

Func<A>(1, 2, 3); // 1
Func<SomeClass>(1, 2); // 2

我知道我可以使用“小技巧” - 将 func 包装到一个类中并对其进行部分专业化,但在我的情况下,这不起作用,因为 Func() 实际上是一些类方法,并且它初始化了该类的一些成员班级。所以 hack-class 应该有指向它的指针并成为它的朋友(因为成员是私有的),这也是问题。

而且这个 hack 看起来有点可怕且难以理解。

c++ templates variadic-templates template-specialization entity-component-system
1个回答
0
投票

您可以通过将函数包装在模板类(结构)中来做到这一点,如下所示:

#include <iostream>
#include <utility>

struct A;
struct SomeClass;

// wrap the functions in a struct
// this can really be helpful
// for template specializations

template<typename T>
struct Wrapper
{
    template<typename... Args>
    static void Func(size_t id, Args&&... args) // use rvalue references for args (avoids copying of temporaries)
    { 
        std::cout << "id = " << id << ", args : ";
        // use std::forward to keep "rvalue" reference(ness)
        ((std::cout << std::forward<Args>(args) << " "),...); // C++17 fold expression
        std::cout << "\n";
    }
};

template<>
struct Wrapper<SomeClass>
{
    template<typename... Args>
    static void Func(std::size_t id, Args&&... args) 
    { 
        std::cout << "SomeClass : ";
        std::cout << "id = " << id << ", args : ";
        ((std::cout << std::forward<Args>(args) << " "),...); // C++17 fold expression
        std::cout << "\n";
    }
};


int main()
{
    Wrapper<A>::Func(1ul, 2, 3); // 1
    Wrapper<SomeClass>::Func(1ul, 2); // 2
}
© www.soinside.com 2019 - 2024. All rights reserved.