标签: static-polymorphism

静态多态性对实现接口有意义吗?

和大家圣诞快乐!

我正在学习静态多态性,并且正在阅读Andrei Alexandrescu关于基于策略的设计的出色著作。我在代码中遇到了以下内容:我有一个接口Interface,指定Foo必须存在该方法。该接口将由class实现Impl。我有以下两种选择:

1)动态多态

class Interface {
public:
    virtual void Foo() = 0;
}

class Impl : public Interface {
public:
    void Foo() {};
}
Run Code Online (Sandbox Code Playgroud)

2)静态多态

class Impl {
{
public:
    void Foo() {};
}

template <class I>
class Interface : public I
{
public:
    void Foo() { I::Foo(); } //not actually needed
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下使用静态多态性有意义吗?与第一种方法相比,第二种方法有什么好处吗?该接口仅指定了某些方法的存在,并且其机制对于不同的实现是相同的-因此与书中描述的情况不太一样,因此我觉得我可能只是在使事情变得过于复杂。

更新:我在运行时不需要多态行为;在编译时已知正确的实现。

c++ polymorphism templates policy-based-design static-polymorphism

5
推荐指数
1
解决办法
1402
查看次数

静态多态性:如何定义接口?

下面是我理解为静态多态的一个非常简单的例子.为什么我不使用动态多态的原因是,我不想妨碍函数的内联PROCESSORop.

template <class PROCESSOR>
void op(PROCESSOR* proc){
    proc->doSomething(5);
    proc->doSomethingElse();
}

int main() {
    ProcessorY py;
    op<ProcessorY>(&py);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

这个例子的问题是:没有明确定义a PROCESSOR必须定义的函数.如果缺少一个,您将收到编译错误.我认为这是不好的风格.

它还有一个非常实际的缺点:IDE的在线帮助当然不能向您展示该对象上可用的功能.

什么是定义公共接口的好/官方方式PROCESSOR

c++ templates static-polymorphism

5
推荐指数
1
解决办法
478
查看次数

为什么haskell没有异构列表

我不明白为什么我不能构建一个看起来像[1,"1",1.1]haskell 的列表.我不认为它是静态类型阻碍因为我认为head现在会有一个不明确的类型,但后来我想到了它并没有理由运行时系统不会实例化不同版本的head任何时候list被输入到它中,因此head [1,"1",1.1]将被输入List->Int,head (tail [1,"1",1.1])并将被输入为List->String.由于运行时已经进行了大量的簿记,为什么它不提供各种前奏函数的更好的多态(或它是通用的)版本?我在这里错过了什么?

polymorphism haskell types list static-polymorphism

4
推荐指数
1
解决办法
2232
查看次数

CRTP - 我可以创建一个私有方法吗?

我正在实现一个静态多态:

template<typename T>
class Base {
public:
    void method() {
         // do something
         impl();
         // do something else
    }
    void impl() { // intended to be private
        static_cast<T*>(this)->impl();
    }
};

class Derived : public Base<Derived> {
public:
     void impl() { // intended to be private
     }
};
Run Code Online (Sandbox Code Playgroud)

此代码是动态多态类的静态实现,其中 void impl() 是虚拟和私有的。

我已经实现了多态性(静态)。但是我必须将方法 void impl() 设为 public 以允许从 Base 类访问它。我希望方法 void impl() 再次成为私有的。可以做到吗?

更新:我不想写

friend class Base<Derived>;
Run Code Online (Sandbox Code Playgroud)

在 Derived 类中,因为它允许 Base 访问 Derived 的所有成员。

c++ crtp static-polymorphism

4
推荐指数
1
解决办法
408
查看次数

C++17 std::variant 比动态多态慢?

我正在关注这个博客,并试图将动态多态性代码替换为使用std::variantand std::visit。但我无法让std::variant+std::visit比 virtual struct impl 更好地工作。速度慢了大约1.3-1.5 倍!(GCC 10.3 -O3 C++17)

用例如下。假设我们正在比较两个表的第 i 行和第 j 行。表可以具有异构类型的列。假设我们可以访问列缓冲区。我正在做的是测试,

def IndexEqual(Table:A, Table:B, int:i, int:j):
  for c in range(A.num_cols):
     if not A.column(c)[i] == B.column(c)[j]:
         return False
  return True

Run Code Online (Sandbox Code Playgroud)

对于动态多态性,我有以下内容intfloat

struct Comp{
  virtual bool comp(size_t i, size_t j) const = 0;
};

struct CompI: public Comp {
  CompI(const int *data_1, const int *data_2) : data1(data_1), data2(data_2) {}

  const int *data1, *data2;
  bool …
Run Code Online (Sandbox Code Playgroud)

c++ polymorphism static-polymorphism c++17 std-variant

3
推荐指数
1
解决办法
1478
查看次数

CRTP 与作为接口或 mixin 的虚拟函数

我想知道如果我从不从基类调用函数(即虚拟调度),使用 CRTP 是否比虚拟函数多态性有任何好处?

这是示例代码。反汇编可以在https://godbolt.org/z/WYKaG5bbG找到。

struct Mixin {
  virtual void work() = 0;
};

template <typename T>
struct CRTPMixin {
  void call_work() {
    static_cast<T*>(this)->work();
  }
};

struct Parent {};
struct Child : Parent, Mixin, CRTPMixin<Child> {
  int i = 0;
  void work() override {
    i ++;
  }
};

Child child;
Mixin& mixin = child;


int main() {
  child.work();
  mixin.work();
  child.call_work();
}
Run Code Online (Sandbox Code Playgroud)

work我发现如果我从接口child或通过接口调用虚函数CRTPMixin,反汇编代码是相同的,只有 static call。如果我调用该函数,Mixin& mixin = child就会发生虚拟调度,并且会为此操作生成更多指令。

我的问题是,如果我正在设计接口/混合类型结构,我只会使用派生类而不是基类来调用它,是否有任何情况 CRTP 会比虚拟函数方法受益更多?

谢谢!

c++ polymorphism virtual-functions crtp static-polymorphism

3
推荐指数
1
解决办法
1191
查看次数

C++中方法和对象选择的静态多态性

尝试在没有基类和虚拟调用的情况下获取编译时方法和对象选择.

情况如下:

struct A {
    void f1()const { cout << "A::f1" << endl;}
    void f2()const { cout << "A::f2" << endl;}
};

struct B {
    void f1()const { cout << "B::f1" << endl;}
    void f2()const { cout << "B::f2" << endl;}
};

class Holder {
    A* _a = nullptr;
    B* _b = nullptr;
public:
    Holder(A* a): _a(a) {}
    Holder(B* b): _b(b) {}
    void f1()const {
        if(_a)       _a->f1();
        else if(_b)  _b->f1();
    }
    void f2()const {
        if(_a)       _a->f2();
        else if(_b)  _b->f2();
    } …
Run Code Online (Sandbox Code Playgroud)

c++ macros templates boost-variant static-polymorphism

2
推荐指数
1
解决办法
123
查看次数

PHP:多态抽象静态方法

我正在尝试这样做,但我没有成功.

abstract class Animal 
{ 
    abstract static function getName();
    static function sayName() { echo self::getName(); }
}
Run Code Online (Sandbox Code Playgroud)

谢谢!

php oop inheritance abstract static-polymorphism

1
推荐指数
2
解决办法
3584
查看次数

奇怪的重复模板与模板叶类

我正在考虑为我的应用程序使用奇怪的重复模板模式.但是,我希望这些类能够在用户定义的类型上运行.我想了解是否可以创建类似于下面所示的结构:

template <class T_leaftype>
class BaseTrajectoryPoint {
};


template <class MyType>
class MyTrajectoryPoint: public BaseTrajectoryPoint<MyTrajectoryPoint> {
    private:    
        MyType A;
};
Run Code Online (Sandbox Code Playgroud)

上面的代码无法编译,出现以下错误:

模板参数列表中参数1的类型/值不匹配'模板类BaseTrajectoryPoint'

有没有其他方法来解决问题?我想使用静态多态,但我更喜欢在基类中定义所有可能的方法.

c++ oop polymorphism crtp static-polymorphism

1
推荐指数
1
解决办法
271
查看次数

奇怪的重复模板模式 - 不能创建超过1个派生类?

我坚持使用这种模式,因为我创建的只有一个派生类得到实例化.用g ++和MSVS检查.具体来说,只创建了我定义的第一个派生类.编译器不会发出任何类型的警告.完整代码如下.

#include <iostream>

static int nodes = 0;

class TreeNode {
private:
    int m_id;
public:
    TreeNode() : 
        m_id(++nodes)
    {}
    TreeNode(int id) :
        m_id(id)
    {
        ++nodes;
    }
    TreeNode* left;
    TreeNode* right;

    int getId() const {
        return m_id;
    }
};


template<typename T>
//typename std::enable_if<std::is_base_of<TreeParser, T>::value>::type
class TreeParser {
protected:
    TreeParser() {
        ++parsers;
    }
public:
    static uint32_t parsers;
    void preorderTraversal(TreeNode* node) {
        if (node != nullptr) {
            processNode(node);
            preorderTraversal(node->left);
            preorderTraversal(node->right);
        }
    }
    virtual ~TreeParser() = default;

    void processNode(TreeNode* node) {              // 2, …
Run Code Online (Sandbox Code Playgroud)

c++ inheritance templates static-polymorphism c++14

0
推荐指数
1
解决办法
78
查看次数