Blu*_*ue7 1 c++ crtp template-meta-programming variadic-templates
我想为可变参数模板中的每种类型创建一个纯虚拟接口。例如,一个类:
overloads_interface<int,float,bool>
Run Code Online (Sandbox Code Playgroud)
定义了功能:
virtual void overload(const int& arg) = 0
virtual void overload(const float& arg) = 0
virtual void overload(const bool& arg) = 0
Run Code Online (Sandbox Code Playgroud)
如果我将其他类型添加到变量模板中,例如
overloads_interface<int,float,bool, std::string>
Run Code Online (Sandbox Code Playgroud)
它将自动添加重载:
virtual void overload(const std::string& arg) = 0
Run Code Online (Sandbox Code Playgroud)
然后,为了实例化此类,我必须实现这些功能,例如:
class concrete : public overloads_interface<int,float,bool> {
public:
virtual void overload(const int& arg) override { /**handle int**/ }
virtual void overload(const float& arg) override { /**handle float**/ }
virtual void overload(const bool& arg) override { /**handle bool**/ }
};
Run Code Online (Sandbox Code Playgroud)
这是我创建此类的最佳尝试:
template<typename... args>
class overloads_interface {
using param_pack = std::tuple<args...>;
static constexpr size_t num_args = sizeof... (args);
template<size_t i = num_args - 1>
struct crtp : public crtp<i - 1> {
using arg = typename std::tuple_element<i, param_pack>::type;
using super = crtp<i - 1>;
using super::overload; // unhide overload from super class
virtual void overload(const arg& arg) = 0;
};
template<>
struct crtp<0> {
using arg = typename std::tuple_element<0, param_pack>::type;
virtual void overload(const arg& arg) = 0;
};
};
Run Code Online (Sandbox Code Playgroud)
但这无法编译:
/main.cpp:21: error: explicit specialization in non-namespace scope ‘class overloads_interface<args>’
template<>
^
/main.cpp:22: error: template parameters not deducible in partial specialization:
struct crtp<0> {
^~~~~~~
Run Code Online (Sandbox Code Playgroud)
并且还有一个crtp我并不真正想要的嵌套类。
我该如何上这堂课?
其它的办法:
template <class T>
struct overloads_helper{
virtual ~overloads_helper() = default;
virtual void overload(const T&) = 0;
};
template <class... Args>
class overloads : public overloads_helper<Args>...{
};
Run Code Online (Sandbox Code Playgroud)
不知道哪个更好,是继承链还是接口的多重继承...