让我们有这个代码
class Foo {
Foo(int) { }
};
Run Code Online (Sandbox Code Playgroud)
然后我们有结果:
int main() {
Foo f1 = Foo(5); // 1: OK, explicit call
Foo f2(5); // 2: OK, implicit call
Foo f3(); // 3: no error, "f3 is a non-class type Foo()", how so?
Foo f4(f1); // 4: OK, implicit call to default copy constructor
Foo f5; // 5: expected error: empty constructor missing
}
Run Code Online (Sandbox Code Playgroud)
你能解释一下案例3中发生了什么吗?
$ cat cons.cpp
#include <iostream>
class Matrix {
private:
int m_count;
public:
Matrix() {
m_count = 1;
std::cout << "yahoo!" << std::endl;
}
};
int main() {
std::cout << "before" << std::endl;
Matrix m1(); // <----
std::cout << "after" << std::endl;
}
$ g++ cons.cpp
$ ./a.out
before
after
$
Run Code Online (Sandbox Code Playgroud)
语法是Matrix m1();做什么的?
我相信它是一样的Matrix m1;.显然我错了.
这样做有什么区别
A a{ A() };
Run Code Online (Sandbox Code Playgroud)
和,
A a( A{} );
Run Code Online (Sandbox Code Playgroud)
避免最烦恼的解析?我什么时候应该使用特定的?
C++ 11允许类内初始化:
struct Foo{
std::vector<std::string> v{3}; // vector of 3 empty strings
};
Run Code Online (Sandbox Code Playgroud)
如果我们想要在类中初始化一个int的向量,我们会得到其他东西:
struct Foo{
std::vector<int> v{3}; // vector of one element with value 3
};
Run Code Online (Sandbox Code Playgroud)
这个问题似乎是语言的限制,正如之前的问题所讨论的那样.但是,如果这不是类内初始化,我们将能够使用括号而不是大括号,并获得所需的结果:
std::vector<int> v(3); // vector of three zeros
Run Code Online (Sandbox Code Playgroud)
但是,由于最令人烦恼的解析,我们不能在课堂上这样做:
struct Foo{
std::vector<int> v(3); // most vexing parse; doesn't compile
};
Run Code Online (Sandbox Code Playgroud)
当然,上面的代码是否是良好的设计实践是有争议的,因为我们可以轻松地将我们想要做的事情移动到构造函数中.但暂时把它放在一边,有没有办法执行所需的初始化,尽可能接近第一个std::string例子,这没有问题?
struct my
{
my(){ std::cout<<"Default";}
my(const my& m){ std::cout<<"Copy";}
~my(){ std::cout<<"Destructor";}
};
int main()
{
my m(); //1
my n(my()); //2
}
Run Code Online (Sandbox Code Playgroud)
预期产量:
1 ) Default
2 ) Copy
Run Code Online (Sandbox Code Playgroud)
实际产量:
我对构造函数调用机制的理解有什么问题?
Note 为简洁起见,我省略了头文件.
考虑以下程序:
#include <fstream>
struct A {};
int main(int argc, char** argv) {
A a(std::fstream(argv[1]));
}
Run Code Online (Sandbox Code Playgroud)
Clang in C++ 1y模式估计MVP被调用,因此a被解析为函数声明:
clang++ -std=c++1y -O3 -Wall -Wextra -pedantic-errors -pthread main.cpp && ./a.out
main.cpp:6:8: warning: parentheses were disambiguated as a function declaration [-Wvexing-parse]
A a(std::fstream(argv[1]));
^~~~~~~~~~~~~~~~~~~~~~~
main.cpp:6:9: note: add a pair of parentheses to declare a variable
A a(std::fstream(argv[1]));
^
( )
Run Code Online (Sandbox Code Playgroud)
我理解MVP,但不是在这个实例中:argv[1]显然是一个表达式,并且之前没有类型,所以如何将这一行解析为函数声明?
argv[1]在编译器已经选择将该行解析为函数声明之后,才会出现语义解释,它会将行消除歧义作为对象声明吗?或者它是一个Clang bug?或者通过对argv [ 1 ]我丢失的令牌的一些解释是完全正常的吗?
这是我的问题:我定义了一个仿函数:
class A {
public:
int operator()(int a, int b) const{
return a + b;
}
};
typedef function<int (int, int)> Fun;
Run Code Online (Sandbox Code Playgroud)
然后我使用匿名仿函数创建一个std :: function对象,我发现一些奇怪的东西.这是我的代码:
Fun f(A());
f(3, 4);
Run Code Online (Sandbox Code Playgroud)
不幸的是,这是错的.错误消息是:
error: invalid conversion from ‘int’ to ‘A (*)()’ [-fpermissive]
error: too many arguments to function ‘Fun f(A (*)())’
Run Code Online (Sandbox Code Playgroud)
但是,当我更改我的代码时,如下所示:
A a;
Fun f(a);
f(3, 4);
Run Code Online (Sandbox Code Playgroud)
要么
Fun f = A();
f(3, 4);
Run Code Online (Sandbox Code Playgroud)
结果是对的.那么,为什么呢?请帮我理解.谢谢.
我正在为我正在教授的课程安排一个基于C++的作业.我有一个函数,我要向学生出口,我希望他们在他们的课程中的不同点上打电话,这样在评分期间,我们可以拦截这些电话,以确保他们在正确的时间做正确的事情.我不希望该代码在提供的启动文件中执行任何操作,因此我只给了函数一个只有一系列语句的主体,这些语句会转换所有参数void以禁止编译器有关未使用参数的警告.在这样做的过程中,我遇到了一个我以前从未见过的不寻常的编译器错误,并且对此站点的搜索没有发现任何有用的信息.
这个简化的测试用例可以最好地说明错误:
void iDontUseMyArguments(int a, int b) {
(void) a; // Explicit cast to void - totally fine!
(void) b;
}
void iDontEither(int a, int b) {
(void) a, b; // Comma expression casted to void, though technically
// b isn't casted to void!
}
void norDoI(int a, int b) {
void(a, b); // ERROR! No idea why this isn't okay.
}
void meNeither(int a, int b) {
(void)(a, b); // Comma expression casted to void - …Run Code Online (Sandbox Code Playgroud) 我有一个构造函数的问题,它没有像我期望的那样工作.
如果我尝试像这样初始化我的类,它将工作,我得到一个可用的对象:
vector<float> v;
MyClass<2> a(v);
Run Code Online (Sandbox Code Playgroud)
但是,如果我尝试构建类似下面的类(应该是等效的),结果是非常意外的.编译或运行程序时没有错误消息/警告.但是如果你尝试在某处使用这个变量并调用它的方法(例如a.doSomething()),它就会崩溃.
我在构造函数中放了一些代码来通知我它是否被使用.事实证明,在这种情况下,构造函数中没有实际执行的代码.
MyClass<2> a(vector<float>());
Run Code Online (Sandbox Code Playgroud)
所以我想知道为什么会这样?第二次申报是非法的吗?
编辑:我将发布一些类的代码
template <int x>
class MyClass {
public:
vector<float> v;
MyClass<x>(vector<float> v1) {
v = v1;
}
};
Run Code Online (Sandbox Code Playgroud) 我在Cpp Quiz 上看到了一个代码[问题 #38]
#include <iostream>
struct Foo
{
Foo(int d) : x(d) {}
int x;
};
int main()
{
double x = 3.14;
Foo f( int(x) );
std::cout << f.x << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
据说这段代码格式不正确,因为Foo f( int(x) );将被视为函数声明而不是 type 的对象声明Foo。
据我所知,这是“最烦人的解析”的一个实例。我的问题是int(x)语句中的这种语法是什么Foo f( int(x) );意思?到目前为止,我只看到了如下函数声明:
Foo f( int ); 和
Foo f( int x );
是一样的Foo f( int x );吗?