- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
编辑:澄清一下,我明白为什么这段代码不起作用,我并不是要修复它,而是想了解如果这段代码可以在没有语义错误的情况下编译会有什么危险。
我发现下面的代码会导致静态语义错误。我知道这是因为 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>
什么时候T
是 U
的基类.那不是写的。
一种实现你想要的方法是创建模板函数:
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/
编辑:澄清一下,我明白为什么这段代码不起作用,我并不是要修复它,而是想了解如果这段代码可以在没有语义错误的情况下编译会有什么危险。 我发现下面的代码会导致静态语义错误。我知道这是因为 std::lis
我想知道 C# 枚举以及重复值会发生什么。我创建了以下小程序来测试: namespace ConsoleTest { enum TestEnum { FirstElem
正如我在另一个 SO 问题中指出的那样,我遇到了 this article .当我通过 MSVC7.1 编译 boost 1.40 时出现了这个问题,并且弹出了几个 C4251 警告。 现在,在阅读上
我有以下弹出窗口代码(客户端请求)。它使用 eval ,我知道这是危险的。有没有办法重写下面的脚本,使其不使用 (eval)? /* exported popup_default , popup_he
NTFS 文件可以有对象 ID。可以使用 FSCTL_SET_OBJECT_ID 设置这些 ID .然而,msdn article说: Modifying an object identifier c
我一直在学习命令行参数解析。关于这个已经有很长的线索了,我不想在这里挑起一个: Using getopts in bash shell script to get long and short com
这个问题在这里已经有了答案: How to configure ContextMenu buttons for delete and disabled in SwiftUI? (4 个回答) 4 个月
为什么在 linux 的中断处理程序中禁止 printk 或 (I/O)。?在什么情况下中断处理程序中的 I/O 会导致 linux 系统中的死锁? 最佳答案 关于 printk(),它是侵入性的。例
不是 Invoking virtual function and pure-virtual function from a constructor 的重复项: 以前的问题与 C++ 03 相关,而不是
我正在使用 lateinit 属性以避免使用 ?运算符(operator)。我有很多 View 属性是第一次在 getViews() 函数中分配的。如果该功能不存在,我的应用程序将与来自 Kotlin
我最近在使用 fputs 时遇到了问题:当使用 fputs 在文本文件中打印一些字符串时,我碰巧得到了除 A-Z、a-z、0-9 之外的其他字符(不属于字符串的字符) .我绝对确保所有字符串都以空字符
在仅包含字节数组的结构上使用 #pragma pack(1) 是否危险/有风险?例如。这个: #pragma pack(1) struct RpcMessage { uint8_t proto
我是一名优秀的程序员,十分优秀!