堆栈模板参数
Stack Template Arguments
关注模板参数
我可以创建一个像这样的堆栈(标准库中的适配器类模板(对象,
stack<int, vector<int>> myStack;
我知道第二个模板参数表示堆栈的底层数据结构。但是为什么下一行没有给出编译时错误呢?
stack<int, vector<string>> myStack;
请注意,我声明的堆栈包含类型为int
的元素,但同时声明的底层数据结构包含string
元素。
从功能上讲,它就像一堆字符串元素一样工作。
您正在做的是未定义的行为。尽管如此,我还是要解释一下为什么它看起来很好
容器适配器std::stack<T, TContainer>
包含几个类型符号,这些符号是常用类型的别名。这里有一个列表。
在这里,我们关注的是std::stack::value_type
。它基本上决定了std::stack::push
和朋友们期望的方法类型:
void push( const value_type& value );
我们还可以看到它是如何定义的:
using value_type = typename TContainer::value_type
因此,在所有操作中使用的类型实际上只是基于第二种类型TContainer
!在您的情况下,这是vector<string>::value_type
,因此value_type
将是string
的别名。未使用用于T
(在您的情况下为int
(的类型。因此,一切似乎都起作用。
但是即使这适用于您的情况和特定编译器,但实际上是不允许的:
如果T与Container::value_type的类型不同,则行为未定义。(自C++17起(
您可以在此处找到此报价的来源。
来自文档:
T-存储的元素的类型。如果T与Container::value_type的类型不同,则行为未定义。(自C++17起(
未定义的行为意味着它可能会编译,甚至可能工作,或者可能会擦除你的硬盘。
它是如何失败的,如果失败了,则取决于实现。
如果非要我猜测,我会想象您的实现正在丢弃int
模板参数,而只是使用Container::value_type
。
一旦我们进入C++17,这将是明确的非法行为。有些编译器可能已经不喜欢这段代码了。。
例如:
#include <stack>
#include <string>
#include <vector>
int main() {
std::stack<int, std::vector<std::string>> s;
s.push(3);
}
无法在OS X(clang,libc++,c++11(下使用进行编译
blah.cc:7:7: error: no matching member function for call to 'push'
s.push(3);
~~^~~~
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/stack:194:10: note:
candidate function not viable: no known conversion from 'int' to 'const value_type' (aka
'const std::__1::basic_string<char>') for 1st argument
void push(const value_type& __v) {c.push_back(__v);}
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/stack:197:10: note:
candidate function not viable: no known conversion from 'int' to 'value_type' (aka 'std::__1::basic_string<char>') for
1st argument
void push(value_type&& __v) {c.push_back(_VSTD::move(__v));}
^
1 error generated.
- 如何使用主参数添加更多堆栈?
- 如何从 x64 程序集中的堆栈中获取参数?
- C++ 参数堆与堆栈,基元类型的数组
- 将参数推送到调用堆栈 (C++) 的可移植方法
- 变量参数列表 后面的'const std::string&'弄乱了堆栈
- 评估虚拟堆栈中的可变参数
- 被调用方如何知道参数是通过寄存器而不是堆栈传递的
- 在 Myfile.exe 中0x00831D39时未处理的异常:0xC00000FD:堆栈溢出(参数:0x0000000
- 如何使用ABI调用过程在堆栈上正确传递Float参数
- C++17 使用选定的构造函数在堆栈中构造数组(每个数组条目的构造函数参数值相同)
- 通过参考数组传递分配的堆栈参数
- 系统堆栈中的两个函数的递归调用(将不同数量的数组作为参数传递)有什么区别
- 功能参数导致堆栈溢出
- 使用 windbg 查找不在堆栈顶部的函数的函数参数
- 参数列表太长了,而堆栈大小ID无限和命令大小约为300 kbyte
- 如何使用在另一个类的构造函数中的堆栈上接受参数的构造函数创建对象
- 指针函数参数已损坏,堆栈已损坏
- stl数据结构的堆栈上输出参数与返回值的效率
- 数组使用的堆栈(参数传递/返回)
- 为变元元组构造参数堆栈