我可以做这个:
#include <iostream>
int counter;
int main()
{
struct Boo
{
Boo(int num)
{
++counter;
if (rand() % num < 7) Boo(8);
}
};
Boo(8);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这将编译正常,我的计数器结果是21.但是,当我尝试创建Boo传递构造函数参数而不是整数文字的对象时,我得到一个编译错误:
#include <iostream>
int counter;
int main()
{
struct Boo
{
Boo(int num)
{
++counter;
if (rand() % num < 7) Boo(num); // No default constructor
// exists for Boo
}
};
Boo(8);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
如何在第二个示例中调用默认构造函数,而不是在第一个示例中调用?这是我在Visual Studio 2017上遇到的错误.
在线C++编译器onlineGDB我得到错误:
error: no matching function for call to ‘main()::Boo::Boo()’ …Run Code Online (Sandbox Code Playgroud) 当这不能在C中编译时我很困惑:
int main()
{
for (int i = 0; i < 4; ++i)
int a = 5; // A dependent statement may not be declaration
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我已经习惯了将要编译的C++.我只是愣了一会儿,直到我记得这里的答案是关于如何在C和C++中将不同的东西视为"陈述".这是关于switch语句的.for循环括号后面的"语句"必须同时出现在C和C++中.这可以在添加分号或创建{}波浪形支架块的情况下完成.
在C++中"int a = 7;" 被视为声明,定义和初始化.CI认为它也被认为是所有这些,但在C中它不被视为"声明".
有人可以准确地澄清为什么在C中这不是一个陈述,而在C++中它是?这让我对一个陈述的概念感到困惑,因为一种语言说的是,而另一种语言则说不是,所以我有点困惑.
有一个类似的问题在这里,但在这一问题的用户似乎有一个更大的阵列,或载体。如果我有:
bool boolArray[4];
Run Code Online (Sandbox Code Playgroud)
我想检查所有元素是否为假,我可以分别检查[0],[1],[2]和[3],也可以循环遍历。由于(据我所知)false应该具有值0,而除0以外的其他任何东西都为true,所以我想到了简单地做:
if ( *(int*) boolArray) { }
Run Code Online (Sandbox Code Playgroud)
这行得通,但是我意识到它依赖于布尔值是一个字节,整数是四个字节。如果我强制转换为(std :: uint32_t)可以,还是一个坏主意?我刚好在一个数组中有3或4个布尔值,并且想知道这是否安全,如果不是,那么是否有更好的方法可以做到。
另外,如果我最终得到超过4个布尔值,但少于8个布尔值,那么我可以使用std :: uint64_t或unsigned long long之类的东西做同样的事情吗?
我想知道是否有办法把它放在一条线上?
if (auto r = getGlobalObjectByName(word)) r->doSomething; // This works fine
if (!auto r = getGlobalObjectByName(word)) r->doSomething; // Says "expected an expression"
if (auto r = getGlobalObjectByName(word) == false) r->doSomething; // Also doesn't work.
Run Code Online (Sandbox Code Playgroud)
我也尝试用额外的括号围绕它,但这似乎不起作用.我发现这在一条线上非常方便.
我遇到了一个有趣的问题,我无法理解发生了什么:
/* I WANT 6 ELEMENTS */
int lvalue = 6;
std::vector<int*> myvector { 6 }; /* WORKS FINE */
std::vector<int*> myvector{ lvalue }; /* DOESN'T WORK */
/* Element '1': conversion from 'int' to 'const unsigned __int64 requires a narrowing conversion */
Run Code Online (Sandbox Code Playgroud)
据我所知,我提供的单个整数参数可以解释为使用 argument 调用构造函数size_type count,也可以解释为采用初始值设定项列表的构造函数。似乎initialiser_list只有当我提供左值时才调用构造函数,而size_t count当我给出右值int(好吧,至少是一个文字)时才调用构造函数。为什么是这样?
这也意味着:
int num_elements = 6;
std::vector<int> myvector{num_elements};
Run Code Online (Sandbox Code Playgroud)
结果仅是大小为 的向量1;
std::vector<int> myvector(num_elements);
Run Code Online (Sandbox Code Playgroud)
结果是一个 size 的向量num_elements,但我认为应该避免这种初始化,因为偶尔会遇到最令人烦恼的解析问题。
我一直在isocpp.org通过阅读FAQ在"链接到此处",并在整个谨慎传来,有std::vector:
std::vector<int> v;
auto a = &v[0]; // Is undefined behaviour but
auto a = v.data(); // Is safe
Run Code Online (Sandbox Code Playgroud)
从实际网站:
void g()
{
std::vector<Foo> v;
// ...
f(v.begin(), v.size()); // Error, not guaranteed to be the same as &v[0]
????????? // Cough, choke, gag; use v.data() instead
}
Run Code Online (Sandbox Code Playgroud)
此外,
&v[0]如果std::vector或std::array为空,则使用未定义的行为,而使用该.data()函数始终是安全的.
我不确定我是否完全理解这一点.::data()返回指向数组开头的指针,并&[0]返回开头的地址.我没有看到这里的区别,我不认为这&[0]是解除引用任何东西(即,不读取元素0处的内存).在Visual Studio中调试构建访问下标[0]导致断言失败,但在发布模式下它没有说什么.此外,两种情况下的地址对于默认构造矢量都是0.
另外我不明白关于::begin()不保证是相同的评论::operator[0].我假设对于向量,begin()迭代器中的原始指针::data(),并且 …
我遇到一个编译错误,说:
试图引用已删除的功能
#include <iostream>
#include <vector>
template <typename T>
struct Container
{
Container() = default;
Container(const Container& other) = delete;
Container(T* ptr) : ptr(ptr) {}
T* ptr;
~Container() { delete ptr; }
};
struct Foo { Foo(int a, int b) {} };
int main()
{
std::vector<Container<Foo>> myvector;
myvector.push_back(new Foo(1, 2)); // I understand why this doesn't work.
myvector.emplace_back((new Foo(1, 2))); // I don't understand why this fails
}
Run Code Online (Sandbox Code Playgroud)
我理解为什么它会在我做的时候尝试引用已删除的构造函数std::vector::push_back(),因为这会复制并需要调用我删除的复制构造函数.
但是std::vector::emplace_back()应该采用它所拥有的类型的构造函数参数.当我向后移动时,我给它一个指向a的指针Foo,这应该转发给Container::Container(T* …
有没有办法将引用作为参数传递给模板类型名参数?我的意思是这样,而不是传递 int,例如,传递对 int 的引用。
template <typename T>
struct Foo
{
Foo(T arg) : ptr(arg) {}
T ptr;
};
int main()
{
int* a = new int(6);
Foo<decltype(a)> foo1(a); // ptr is a copy of a pointer
Foo<decltype(&a)> foo1(&a); // ptr seems to be a pointer to a pointer
}
Run Code Online (Sandbox Code Playgroud)
我知道我可以通过在类中将它设为 T& 来使 'ptr' 成员成为对指针的引用,但我想知道这是否可以通过传递给模板参数的参数来完成。
我在Visual Studio 2017上.最近,因为我不喜欢C++的不符合标准,所以我继续并禁用了选项中的非标准语言扩展.到现在为止还挺好.现在我有一个问题.
#include <iostream>
#include <vector>
struct Vertex
{
Vertex(float pos) { }
Vertex(Vertex& other) { }
};
std::vector<Vertex> arrayOfVertices;
int main()
{
arrayOfVertices.emplace_back(7.f);
}
Run Code Online (Sandbox Code Playgroud)
这不会在Visual Studio中编译,它给出的唯一错误是:
"编译器中发生内部错误"
如果我启用语言扩展,它编译得很好.如果我禁用语言扩展并使复制构造函数采用const Vertex&它编译好.
所以我在一些在线编译器上尝试了GCC,如果复制构造函数没有采用const引用参数,它将无法编译,从而产生各种错误.似乎最有意义的是:
错误:从'Vertex'类型的右值开始无效初始化'Vertex&'类型的非const引用
我认为复制构造函数不必是const,在我的情况下我想修改另一个引用中的东西.我知道非const参数不能采用r值引用,但我测试了它,结果发现在vector::emplace_back()拷贝构造函数中根本没有调用:
#include <iostream>
#include <vector>
struct Vertex
{
Vertex(float pos)
{
std::cout << "Calling constructor\n";
}
Vertex(const Vertex& other)
{
std::cout << "Calling copy constructor\n";
}
};
std::vector<Vertex> arrayOfVertices;
int main()
{
arrayOfVertices.emplace_back(7.f); // Normal constructor called if const,
// doesn't compile if …Run Code Online (Sandbox Code Playgroud) 我无法理解函数签名和指针.
struct myStruct
{
static void staticFunc(){};
void nonstaticFunc(){};
};
int main()
{
void (*p)(); // Pointer to function with signature void();
p = &myStruct::staticFunc; // Works fine
p = &myStruct::nonstaticFunc; // Type mismatch
}
Run Code Online (Sandbox Code Playgroud)
我的编译器说类型myStruct::nonstaticFunc()是void (myStruct::*)(),但不是指向它的指针类型?
我问,因为当你创建一个std::function对象时,你传递了你想要它指向的函数的函数签名,比如:
std::function<void()> funcPtr; // Pointer to function with signature void()
not
std::function<void(*)()> funcPtr;
Run Code Online (Sandbox Code Playgroud)
如果我不得不根据void()我会说的模式猜测:
void myStruct::();
or
void (myStruct::)();
Run Code Online (Sandbox Code Playgroud)
但这不对.我不明白为什么我应该添加一个星号,因为它是非静态的而不是静态的.换句话说,指针void(* )()指向带签名的函数void(),而指针void(myStruct::*)()指向带签名的函数是什么?