我正在使用带有一组类的继承。其中一个子类与std::function(ReturnTy<ParamTypes...>)
参数一起使用ParamTypes
。类签名和构造函数如下:
template<class ReturnTy, class... ParamTypes>
class Child : public Interface
{
public:
Child(ReturnTy default_value, ParamTypes... args)
: func_set_(false)
, m_Args(std::make_tuple(std::forward<ParamTypes>(args)...))
, m_ReturnValue(default_value)
{}
private:
bool func_set_;
std::function<ReturnTy(ParamTypes...)> m_Funciton;
std::tuple<ParamTypes...> m_Args;
ReturnTy m_ReturnValue;
};
我的问题是我想专门研究没有参数的情况。此外,我还想专门研究ReturnTy=void
并且有参数的情况。我找到了一个与我正在寻找的here接近的答案,但是它并不能完全涵盖我要执行的操作,因为该问题使用编译时整数作为模板参数,而我在使用类型。它还涉及函数而不是类。我感觉自己已经接近了,但是我需要一些帮助才能使我的代码正常工作。
作为参考,这是我对其他专业(简称)的看法:
template<class ReturnTy>
class Child<ReturnTy> : public Interface
{
public:
Child(ReturnTy default_value)
: // The same as first class without m_Args
{}
private:
// Same as first class without m_Args
};
template<class... ParamTypes>
class Child<void, ParamTypes...> : public Interface
{
public:
Child(ParamTypes... args)
: // Same as first class without m_ReturnValue
private:
// Same as first class without m_ReturnValue
};
编辑
具体来说,该问题来自以下代码行:
Child<void> obj1(5);
答案 0 :(得分:1)
问题是您的专长处于同一级别(没有人比另一个专长),并且Child<void>
两者都匹配。
如果您希望Child<void>
与Child<ReturnTy>
大小写匹配(否则解决方案简单而优雅:在第二种专业化方法中,将ParamTypes...
列表拆分为Par0
强制性类型和其他ParamTypes...
)类型,我看不到简单而优雅的解决方案。
目前,我能想到的最好的办法就是添加一个间接级别(添加一个Child_base
类),同时还添加一个模板参数以显式显示所需的解决方案。
也许可以用一种更简单的方式制作(抱歉,但是在这一刻,我可以尝试使用编译器),但是我可以想象如下
template <typename RT, bool, typename ... PTs>
class Child_base : public Interface
{
// general case (no empy PTs... list and no void return type)
};
template <typename ... PTs>
class Child_base<void, true, PTs...> : public Interface
{
// case return type is void (also empy PTs... list)
};
template <typename RT>
class Child_base<RT, false> : public Interface
{
// case return type only, but not void, and empy PTs
};
template <typename RT, typename ... PTs>
class Child
: public Child_base<RT, std::is_same_v<void, RT>, PTs...>
{
};
通过这种方式,Child<void>
继承自Child_base<void, true>
的第一个专业化的Child_base
,但不匹配第二个专业化的专业。
我提出了另一种关于Child
的方法:与其将其定义为派生自Child_base
的类,不如尝试将其定义为using
的{{1}}别名>
Child_base
也许用更合适的名称重命名template <typename RT, typename ... PTs>
using Child = Child_base<RT, std::is_same_v<void, RT>, PTs...>;
。
答案 1 :(得分:0)
问题是config/horizon.php
匹配2个(部分)专业(其中没有一个比另一个更专业):
Child<void>
与template<class ReturnTy> class Child<ReturnTy>
[ReturnTy = void]
,带有空包装。您因此需要额外的专业化:
template<class... ParamTypes> class Child<void, ParamTypes...>