Как правильно использовать шаблонную функцию - PullRequest
0 голосов
/ 09 июня 2018

У меня есть некоторые структуры и перечисления, которые выглядят следующим образом:

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))
}

Не могли бы вы помочь мне привести в порядок различные шаблоны?

1 Ответ

0 голосов
/ 09 июня 2018

Частичная специализация функций может быть достигнута путем переноса реализации функции на шаблон объекта функции, который, поскольку он является шаблоном класса, может быть частично специализированным.

пример:

#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{});
}

Однако, если это реальный дизайн, он кажется немного подозрительным.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...