我有一个模板化函数,它以std::array任意大小作为参数。它看起来大致是这样的:
template <size_t n>
void foo(const std::array<int, n>& numbers) {
for (const auto & number: numbers) {
// ... do stuff ...
}
}
Run Code Online (Sandbox Code Playgroud)
我可以这样称呼它:
std::array<int, 2> ints = {4, 5};
foo(ints);
Run Code Online (Sandbox Code Playgroud)
一切都很好。
不幸的是,我无法使用初始化列表直接调用该函数。这段代码:
foo({4, 5});
Run Code Online (Sandbox Code Playgroud)
给了我以下错误:
错误:没有匹配的成员函数来调用“foo” 注意:候选模板被忽略:无法推断模板参数“n”
有没有办法使用初始化列表或类似的东西使我的函数工作?
我正在尝试在 main 中使用带有冒号的构造函数初始值设定项列表,但它无法在 Microsoft Visual Studio 2019 中编译(错误:标识符“名称”未定义且预期为 '}'),但它编译并打印输出在 Linux 中使用 g++(版本 10.2.0)没有任何问题。
我也尝试过不同版本的 MSVC,如 C++14、C++17,但没有结果。我知道 C++11 的所有可能的初始化,但我必须使用带有冒号 (:) 的那个。
有没有办法在 MSVC 中做到这一点?
提前致谢!
#include <string>
#include <iostream>
class Spell {
private:
std::string name;
std::string action;
public:
Spell(std::string name, std::string action) : name(name), action(action) {}
void print() {
std::cout << name;
}
};
int main() {
Spell* spell = new Spell{ name : "test", action : "lol" }; //HERE
spell->print();
}
Run Code Online (Sandbox Code Playgroud) 假设我有一个没有名为 的默认构造函数的类Foo。
如果我使用std::vector,我可以这样做:
std::vector<Foo> vec(100, Foo(5));
Run Code Online (Sandbox Code Playgroud)
这将创建一个包含 100 个元素的向量,每个元素都有值Foo(5)。
我该如何做同样的事std::array<Foo, 100>?
我显然不想Foo(5)在初始化列表中显式列出 100 次。但我不能等到数组构造完成后才对其进行初始化,因为缺少默认构造函数将产生编译器错误。
通过提供类似于“placement new”或函数的显式构造函数参数,该解决方案还允许我避免复制构造函数emplace。
我有一堆使用硬件(FPGA)寄存器的代码,其大致形式如下:
struct SomeRegFields {
unsigned int lower : 16;
unsigned int upper : 16;
};
union SomeReg {
uint32_t wholeReg;
SomeRegFields fields;
};
Run Code Online (Sandbox Code Playgroud)
(这些寄存器类型中的大多数都比较复杂。这是说明性的。)
在清理一堆通过以下方式设置寄存器的代码时:
SomeReg reg1;
reg1.wholeReg = 0;
// ... assign individual fields
card->writeReg(REG1_ADDRESS, reg1.wholeReg);
SomeReg reg2;
reg2.wholeReg = card->readReg(REG2_ADDRESS);
// ... do something with reg2 field values
Run Code Online (Sandbox Code Playgroud)
我有点心不在焉,不小心得到了以下结果:
SomeReg reg1{ reg1.wholeReg = 0 };
SomeReg reg2{ reg2.wholeReg = card->readReg(REG2_ADDRESS) };
Run Code Online (Sandbox Code Playgroud)
当然,该reg1.wholeReg =部分是错误的,应该删除。
让我烦恼的是它可以在 MSVC 和 GCC 上编译。我预计这里会出现语法错误。此外,有时它工作正常,并且值实际上被正确复制/分配,但其他时候,即使返回的寄存器值非 0,它也会导致 0 值。它是不可预测的,但在哪些情况有效和哪些情况无效的运行之间似乎是一致的。
知道为什么编译器不将其标记为错误语法,以及为什么它在某些情况下似乎有效但在其他情况下会中断?当然,我认为这是未定义的行为,但为什么它会改变通常看起来几乎相同的调用(通常是背靠背)之间的行为? …
我很难理解它是如何std::initializer_list工作的。我检查了其他问题,但没有发现任何相关内容(或者也许我没有看到它?)。
假设我有这个:
template<typename T>
struct Point
{
T x,y;
};
template<typename T>
struct A
{
std::vector<Point<T>> v;
};
Run Code Online (Sandbox Code Playgroud)
然后我可以构建:
int main()
{
A<int> a{ std::vector<Point<int>> { {4,4}, {5,5},{6,6} } };
}
Run Code Online (Sandbox Code Playgroud)
但我想让事情变得更简单,所以我可以写:
int main()
{
A<int> a( { {4,4}, {5,5},{6,6} } );
}
Run Code Online (Sandbox Code Playgroud)
我试过:
template<typename T>
struct A
{
std::vector<Point<T>> v;
template<typename U>
A( const std::initializer_list<Point<U>>& il ) : v{il}
{}
};
Run Code Online (Sandbox Code Playgroud)
但这失败了,请参阅现场演示。
我怎样才能编写一个允许这样做的构造函数?这可能吗?
下面的代码片段无法编译。我尝试了不同的初始化程序,但无法编译。
\n#include <array>\n#include <semaphore>\n\n\nint main()\n{\n std::array<std::binary_semaphore, 4> semaphores { {0}, {0}, {0}, {0} };\n auto& [ lock1, lock2, lock3, lock4 ] { semaphores };\n}\nRun Code Online (Sandbox Code Playgroud)\n这是错误消息:
\n#include <array>\n#include <semaphore>\n\n\nint main()\n{\n std::array<std::binary_semaphore, 4> semaphores { {0}, {0}, {0}, {0} };\n auto& [ lock1, lock2, lock3, lock4 ] { semaphores };\n}\nRun Code Online (Sandbox Code Playgroud)\n难道不能声明一个binary_semaphores 数组吗?正确的语法是什么?
从其他帖子中读取代码,我看到的是这样的东西.
struct Foo {
Foo() : mem(0) {}
int mem;
};
Run Code Online (Sandbox Code Playgroud)
mem(0){}在这种情况下做了什么,特别是关于花括号?我以前从未见过这个,也不知道我会在哪里找到这个.我知道mem(0)会将mem初始化为0,但为什么{}?
谢谢.
我一直在用这种方式初始化我的一个结构而没有任何问题很长一段时间:
struct MyStruct
{
float firstArr[4];
float secondArr[4];
float thirdArr[4];
float fourthArr[4];
};
void Function()
{
std::vector<MyStruct> myArr;
myArr.push_back // This works fine
({
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 }
});
}
Run Code Online (Sandbox Code Playgroud)
当我开始从Parent派生我的结构时,我不再能够这样做了.
struct Parent
{
// Nothing
};
struct MyStruct: Parent
{
float firstArr[4];
float secondArr[4];
float thirdArr[4];
float fourthArr[4];
};
void Function()
{
std::vector<MyStruct> myArr;
myArr.push_back // This gets compiler …Run Code Online (Sandbox Code Playgroud) 在一个曾经使用过许多智能指针并且现在使用原始指针的大型框架中,我经常遇到这样的情况:
class A {
public:
int* m;
A() : m() {}
};
Run Code Online (Sandbox Code Playgroud)
原因是因为int* m曾经是一个智能指针,所以初始化列表称为默认构造函数.现在这int* m是一个原始指针,我不确定这是否相当于:
class A {
public:
int* m;
A() : m(nullptr) {}
};
Run Code Online (Sandbox Code Playgroud)
如果没有明确nullptr的A::m还是初始化为零?看看没有优化objdump -d使它看起来是肯定的,但我不确定.我觉得答案是肯定的原因是由于这一行objdump -d(我在objdump -d下面发布了更多内容):
400644: 48 c7 00 00 00 00 00 movq $0x0,(%rax)
Run Code Online (Sandbox Code Playgroud)
尝试查找未定义行为的小程序:
class A {
public:
int* m;
A() : m(nullptr) {}
};
int main() {
A buf[1000000];
unsigned int count = 0;
for (unsigned int …Run Code Online (Sandbox Code Playgroud) 我想用值初始化2 D向量,它给了我这个错误:
IntelliSense: initialization with '{...}' is not allowed for object of type "std::vector<std::vector<int, std::allocator<int>>, std::allocator<std::vector<int, std::allocator<int>>>>"
Run Code Online (Sandbox Code Playgroud)
使用以下内容时,我会得到以上错误?
vector<vector<int>> A =
{ { 0, 0, 0, 0, 0, 0 },
{ 0, 1, 2, 2, 4, 1 },
{ 0, 3, 4, 1, 5, 2 },
{ 0, 2, 3, 3, 2, 4 },
{ 0, 4, 1, 5, 4, 6 },
{ 0, 6, 3, 2, 1, 3 } };
Run Code Online (Sandbox Code Playgroud) c++ ×10
initializer-list ×10
c++20 ×2
constructor ×2
arrays ×1
c++11 ×1
compilation ×1
g++ ×1
inheritance ×1
pointers ×1
stdarray ×1
stl ×1
struct ×1
templates ×1
vector ×1
visual-c++ ×1