我想做类似下面代码的操作,但我不想实施func()
两次,因为它将是相同的实现。你有任何建议如何实现这个目标吗?
template <typename First, typename... Rest>
class Base : public Base<Rest...> {
public:
using Base<Rest...>::func;
void func(First object) {
// implementation
}
};
template <typename First>
class Base<First> {
public:
void func(First object) {
// implementation
}
};
struct X {};
struct Y {};
struct Z {};
class Derived : public Base<X, Y, Z> {};
// ...
Derived d;
d.func(X{});
d.func(Y{});
d.func(Z{});
答案 0 :(得分:3)
使用多重继承和额外的using
指令:
template <typename First, typename... Rest>
struct Base : Base<First>, Base<Rest...> {
using Base<First>::func;
using Base<Rest...>::func;
};
template <typename First>
struct Base<First> {
void func(First object) {/*...*/}
};
答案 1 :(得分:2)
这可能是一个解决方案吗? (将func的定义移到公共基础?)
template <class First>
class Func_impl
{
public:
void func(First obj) {
// implementation
}
}
template <typename First, typename... Rest>
class Base : public Base<Rest...>, Func_impl<First> {
public:
// no need to declare func here
};
template <typename First>
class Base<First> : public Func_impl<First> {
public:
// no need to declare func here
};
答案 2 :(得分:2)
我建议(1)声明Base
接收零个或多个类型
template <typename...>
class Base;
(2)转换接收一种或多种类型
的部分特化中的递归版本template <typename First, typename... Rest>
class Base<First, Rest...> : public Base<Rest...> {
public:
using Base<Rest...>::func;
void func(First object) {
// implementation
}
};
(3)删除只有一个参数的部分特化和(4)添加一个接地案例零参数专业化
template <>
class Base<>
{ public: void func () {} };
在地面专业化中观察虚拟(没有实现)func()
:func
需要它(需要名称为using Base<Rest...>::func;
的东西)。
以下是一个完整的工作示例。
#include <iostream>
template <typename...>
class Base;
template <typename First, typename... Rest>
class Base<First, Rest...> : public Base<Rest...> {
public:
using Base<Rest...>::func;
void func(First object)
{ std::cout << "func() recursive" << std::endl; }
};
template <>
class Base<>
{ public: void func () {} };
struct X {};
struct Y {};
struct Z {};
class Derived : public Base<X, Y, Z> {};
int main()
{
Derived d;
d.func(X{});
d.func(Y{});
d.func(Z{});
}
答案 3 :(得分:1)
在C ++ 17中,有一个基于&#34; variadic&#34;的简单非递归解决方案。多重继承和&#34;变量使用&#34; (使用声明中的包扩展)。虽然这不是你要求的,但我认为值得回答。作为奖励,每种类型的实现都知道它们在原始序列中的索引。
http://coliru.stacked-crooked.com/a/f67d00da68226d5f
#include <iostream>
#include <utility>
template<std::size_t i, class T>
struct IndexedNode {
void func(T) {
std::cout << __PRETTY_FUNCTION__ << std::endl;
}
};
template<class Indices, class... Ts>
struct IndexedBase;
template<std::size_t... is, class... Ts>
struct IndexedBase<
std::index_sequence<is...>,
Ts...
>
: IndexedNode<is, Ts>...
{
using IndexedNode<is, Ts>::func...;
};
template<class... Ts>
struct Base
: IndexedBase<std::index_sequence_for<Ts...>, Ts...>
{
using Is = std::index_sequence_for<Ts...>;
using IndexedBase<Is, Ts...>::func;
};