我正在编写一个用于遗传算法/神经进化的库。当前,该程序使用多态性来允许多种类型的基因组。所以我的代码看起来像这样:

class Genome { // Interface
    // Some abstract functions
}

class SpecificGenome : public Genome {
    // implementation
public:
    int do_something(int x); // Specific behavior, which only this SpecificGenome has
}

class Population {
public:
    Population(size_t population_size, std::function<std::unique_ptr<Genome>()> create_genome);
    // Some functions
    std::vector<std::unique_ptr<Genome>> members;
}

std::unique_ptr<Genome> create_specific_genome(){
    return std::unique_ptr<Genome>(std::make_unique<SpecificGenome>());
}

int main() {
    Population p(150, &create_specific_genome);

    int y = static_cast<SpecificGenome>(*p.members[0].get())->do_something(4);
}


我正在考虑对其进行更改,以便使用模板而不是多态性,因为每个基因组都编码一个现象,该现象可以具有任何类型的行为,并且与其他现象类型没有任何共同点,并且某些基因组使用直接编码方案并且不必解码为现象。因此,每个基因组都必须由用户转换为其对应的子类,以暴露其行为,这看起来非常丑陋。
问题在于,基因组的每个子类都是一个基因组,需要有一些特定的功能才能起作用,因此多态性是很有意义的。

编辑:
现在的问题还不清楚,因此我想补充一些解释。我希望能够创建具有任何类型的基因组(NeuralNetwork,NEAT Genome,图像等)的种群,因此我使用接口和子类进行了此操作,以便种群中的载体可以使用基因组指针。这很有用,因为每种基因组类型都需要具有特定的方法,例如交叉和突变。问题出在,当我想使用特定功能(如计算神经网络的输出),基因组解码或获取图像的像素数据时,基因组解码。这使我产生疑问,如果使用模板而不是继承会更好。

最佳答案

模板可能会更好地帮助您解决问题,但是还有其他含义。

例如,您的列表不能包含不同的基因组类型。它必须是同一类型。如果需要异质性,则必须实现某种类型的擦除。

这是一个看起来像您的示例,但具有静态多态的示例:

// no inheritance
class SpecificGenome {
public:
    int do_something(int x);
}

template<typename G, typename C>
class Population {
public:
    Population(size_t population_size, C create_genome);

    // no need for pointers. Values work just fine.
    std::vector<G> members;
}

// Deduction guide using the create_genome function return type
template<typename C>
Population(std::size_t, C) -> Population<std::invoke_result_t<C>, C>;

SpecificGenome create_specific_genome() {
    return SpecificGenome{};
}

int main() {
    // Uses class template argument deduction
    Population p(150, create_specific_genome);

    int y = p.members[0].do_something(4);
}




顺便说一句,如果仍然使用std::unique_ptr,则可以使用更好的语法:

std::unique_ptr<Genome> create_specific_genome() {
    // no need for casts
    return std::make_unique<SpecificGenome>();
}

// no need for calls to `get`.
int y = static_cast<SpecificGenome&>(*p.members[0]).do_something(4);

关于c++ - 模板与多态,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/56008187/

10-13 08:06