首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >带有可变模板的静态继承

带有可变模板的静态继承
EN

Stack Overflow用户
提问于 2020-10-17 22:18:42
回答 2查看 62关注 0票数 2

我正在尝试使用std::conditional来实现静态继承。我的child类有两个可能的父类:parent_one (它应该根据传递的类型保存多个变量)和parent_two (它需要两种类型)。我使用标记分派来区别我想要继承的类。

现在是问题所在。当我调用child并用两种类型标记它从parent_one继承时,它按预期工作。但是,如果我试图将任意数量的类型传递到child中,以便从parent_one继承,则会得到错误:

代码语言:javascript
复制
static_polymorphism.cpp: In instantiation of ‘class child<foo_type, int, int, double, float>’:
static_polymorphism.cpp:110:41:   required from here
static_polymorphism.cpp:99:7: error: wrong number of template arguments (4, should be 2)
   99 | class child : public std::conditional_t<
      |       ^~~~~
static_polymorphism.cpp:90:7: note: provided for ‘template<class T, class F> class parent_two’
   90 | class parent_two {
      |       ^~~~~~~~~~
static_polymorphism.cpp: In function ‘int main(int, char**)’:
static_polymorphism.cpp:111:9: error: ‘class child<foo_type, int, int, double, float>’ has no member named ‘log’
  111 |   first.log();

如果我理解正确的话,编译器应该根据我的标记分派来生成代码。这意味着它应该从parent_one创建重载类-N(基于传递的类型),从parent_two创建M(基于传递的类型)。但是,由于某些原因,我不知道它是否接受类型的变量计数。能告诉我我做错了什么吗?

实现就在这里。

代码语言:javascript
复制
using one_t = struct foo_type{};
using two_t = struct bar_type{};

template <typename ... TYPES>
class parent_one {
public:
  parent_one() = default;
  void log() {
    std::cout << "parent_one" << std::endl;
  }
};

template <typename T, typename F>
class parent_two {
public:
  parent_two() = default;
  void log() {
    std::cout << "parent_two" << std::endl;
  }
};

template <typename T, typename ... ARGS>
class child : public std::conditional_t<
    std::is_same_v<T, one_t>,
    parent_one<ARGS...>,
    parent_two<ARGS...>
  >
{
public:
  child() = default;
};

int main(int argc, char *argv[]) {
  child<one_t, int, int, double, float> first;
  first.log();

  child<two_t, int, int> second;
  second.log();
  return 0;
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-10-17 22:34:42

代码语言:javascript
复制
std::conditional_t<
    std::is_same_v<T, one_t>,
    parent_one<ARGS...>,
    parent_two<ARGS...>
>

这里,在检查条件之前,将对这两个选项进行验证。std::conditional_t并不神奇,它只是一个普通的模板,它需要所有的模板参数都是有效的,然后才能做任何事情。

您需要延迟将模板参数替换为父模板,直到选择了其中一个替代方案。这里有一个可能的解决方案:

代码语言:javascript
复制
template <template <typename...> typename T>
struct delay
{
    template <typename ...P>
    using type = T<P...>;
};
// ...
class child :
    public std::conditional_t<
        std::is_same_v<T, one_t>,
        delay<parent_one>,
        delay<parent_two>
    >::template type<ARGS...> 
{
    // ...
};
票数 2
EN

Stack Overflow用户

发布于 2020-10-17 22:43:34

你可能是经典的:

代码语言:javascript
复制
template<class T, class... Args> struct child: parent_one<Args...> {};

template<class T, class A, class B> struct child<T, A, B>: parent_two<A, B> {};

template<class A, class B> struct child<one_t, A, B>: parent_one<A, B> {};

(这两个专门化可以结合为一个与requires (!std::is_same_v<T, one_t>))。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64407908

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档