首页 > 解决方案 > 如何正确使用可变参数模板函数

问题描述

我有一些结构和枚举,如下所示:

enum NUM
{
   A = 0,
   B,
   C
};

struct X{};
struct Y{};

我想为一个看起来像这样的函数创建一个可变参数模板:

template<NUM n, typename...Args>
void func(const Args&...a);

在这种情况下,我想专门化模板功能func

如果NUM::A定义func

template<> void func<A, X>(const X& x)
{
   var.emplace_back(std::make_shared<SomeClass>(x));
} 

如果NUM::B定义func

template<> void func<B,X,Y>(const X& x, const Y& y)
{
   var.emplace_back(std::make_shared<SomeOtherClass>(x,y))
}

你能帮我用可变参数模板整理一下吗?

标签: c++templates

解决方案


函数的部分特化可以通过将函数的实现推迟到函数对象模板来实现,因为它是一个类模板,所以可以部分特化。

例子:

#include <memory>
#include <vector>

enum NUM
{
   A = 0,
   B,
   C
};

struct X{};
struct Y{};

// guess at missing code in question

struct SomeBase
{
    virtual ~SomeBase() noexcept;
};

struct SomeClass : SomeBase
{
    SomeClass(const X&);
};

struct SomeOtherClass : SomeBase
{
    SomeOtherClass(const X&, const Y&);
};

std::vector<std::shared_ptr<SomeBase>> var;

// helper base class
struct func_impl_common
{
    func_impl_common(std::vector<std::shared_ptr<SomeBase>>& var) : var(var) {}
    std::vector<std::shared_ptr<SomeBase>>& var;
};

// general template
template<NUM n, typename...Args> struct func_impl;

// now specialise for A X
template<> struct func_impl<A, X> : func_impl_common
{
    using func_impl_common::func_impl_common;
    void operator()(X const& x) const
    {
       var.push_back(std::make_shared<SomeClass>(x));
    }
};

// now specialise for B X Y
template<> struct func_impl<B, X, Y> : func_impl_common
{
    using func_impl_common::func_impl_common;
    void operator()(X const& x, Y const& y) const
    {
       var.push_back(std::make_shared<SomeOtherClass>(x, y));
    }
};

// define func in terms of function object template

template<NUM n, typename...Args>
void func(const Args&...a)
{
    auto op = func_impl<n, Args...>(var);
    op(a...);
}

// test

int main()
{
    func<A>(X{});
    func<B>(X{}, Y{});
}

然而,如果这是一个真正的设计,它似乎有点可疑。


推荐阅读