gpt4 book ai didi

c++ - 派生类的模板类作为函数的参数 - 危险?

转载 作者:行者123 更新时间:2023-11-30 03:14:34 26 4
gpt4 key购买 nike

编辑:澄清一下,我明白为什么这段代码不起作用,我并不是要修复它,而是想了解如果这段代码可以在没有语义错误的情况下编译会有什么危险。

我发现下面的代码会导致静态语义错误。我知道这是因为 std::list 是一个模板类,这意味着 std::list<foo*>是不同于 std::list<bar*> 的类型

我的问题是,编译器是否允许从 std::list<bar*> 进行这种类型的转换?至 std::list<foo*>在第二次调用 print_all 时,可能有什么危险?

我搜索了整个网站,但找不到可能发生的坏事的示例。我也曾尝试想过这样的例子,但我不确定这些例子是否正确或准确。(例如,如果编译器允许这样做,我是否可以将 foo* 对象添加到 print_all() 的 bar 列表中,因为它已转换为列表?)。

#include <list>
using std::list;
class foo {
// ...
};
class bar : public foo {
// ...
};

static void print_all(list<foo*>& L) {
// ...
}

list<foo*> LF;
list<bar*> LB;
// ...
print_all(LF); // works fine
print_all(LB); // static semantic error

最佳答案

list<foo*>list<bar*>是两个完全不同的类,它们之间没有任何联系,除了从同一模板生成的蜜蜂 std::list (template<class T, class Allocator = std::allocator<T>> class list;)。因此它们之间没有转换,除非模板的作者 std::list显式写了 std::list<T, A> 之间的转换和 std::list<U, A>什么时候TU 的基类.那不是写的。

一种实现你想要的方法是创建模板函数:

template <class T, class A>
void print_all(std::list<T*, A>& l)

现在,需要注意一些注意事项:

我看不出您为什么要创建该静态成员。我会让它成为自由函数,但是我会把它放在一个带有 foo 的命名空间中和 bar

如果你想严格限制它的使用foo及其派生类,您可以使用 sfinae 来完成:

template <class T, class A, class E = std::enable_if_t<std::is_base_of_v<foo, T>>>
auto print_all(std::list<T*, A>& l)
{
}

最后你应该考虑把它变成惯用的 C++ 打印方式,也就是流并添加 operator<<(std::ostream&, const std::list<T*, A>&)连同 operator<<(std::ostream, const foo&)也许是 foo 上的虚拟打印功能.在与 foo 相同的命名空间中定义它们尤为重要。和 bar .

关于c++ - 派生类的模板类作为函数的参数 - 危险?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57701367/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com