我有以下代码:
enum nums {
a
};
class cls {
public:
cls( nums );
};
void function()
{
cls( a );
}
Run Code Online (Sandbox Code Playgroud)
当我尝试使用gcc编译它时,我收到以下错误:
test.cpp: In function ‘void function()’:
test.cpp:12:10: error: no matching function for call to ‘cls::cls()’
test.cpp:12:10: note: candidates are:
test.cpp:7:3: note: cls::cls(nums)
test.cpp:7:3: note: candidate expects 1 argument, 0 provided
test.cpp:5:7: note: cls::cls(const cls&)
test.cpp:5:7: note: candidate expects 1 argument, 0 provided
make: *** [test] Error 1
Run Code Online (Sandbox Code Playgroud)
如果我用这个替换函数:
void function()
{
cls name( a );
}
Run Code Online (Sandbox Code Playgroud)
一切正常.如果我使用带有两个参数的构造函数,它也可以工作.如果我在构造函数中添加"explicit",它就不起作用.
我得到gcc以某种方式将其解析为定义名为"a"的类型为"cls"的变量,但我不熟悉这种定义变量的语法.在我看来,这是一个定义cls类型的匿名临时变量的语句,传递"a"是参数.
用gcc …
C ++中指向成员解引用运算符(.*和->*)的指针的优先级为4,而函数调用运算符的优先级为2。这几乎可以保证需要括号:
#include <iostream>
struct A {
int b;
int func1( int a ) { return a+b+1; }
int func2( int a ) { return 2*a+b; }
};
int main() {
A a;
a.b = 3;
int (A::*ptr)(int);
ptr = &A::func1;
std::cout<<
(a.*ptr) // <- these parenthesis
( 2 ) << "\n";
}
Run Code Online (Sandbox Code Playgroud)
在我看来,将.*优先级2 定义为(具有从左到右的关联性)将不需要括号,而不会出现明显的不良副作用。
选择此优先级的原因是什么?
我想知道用户是否是 root,而不关心该用户是否使用类似 fakeroot 的工具。
我尝试了这些功能getuid(),geteuid()并且getlogin(),但是当我启动fakeroot命令时,每个功能都发送我自己的帐户信息,而不是root.
对于这段代码:
printf("%d %d %s\n", getuid(), geteuid(), getlogin());
Run Code Online (Sandbox Code Playgroud)
这是我得到的:
% fakeroot ./busybox rm
1000 1000 julien
Run Code Online (Sandbox Code Playgroud)
当我想要得到类似的东西时:
0 0 root
Run Code Online (Sandbox Code Playgroud)
(登录就足够了)
在回答之前:这不是关于如何让这段代码做我想做的事情的问题.我已经知道如何做到这一点(见本问题的结尾).这是一个关于理解编译器为什么会这样做的问题.
请考虑以下(简化)代码:
#include <iostream>
void operator>>( std::istream &stream, char chr )
{
std::cout<<"Called "<<chr<<"\n";
}
int main()
{
char c='b';
std::cin>>c;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
用gcc 4.8.2和-Wall -Wextra编译产生一个无关警告(流未使用).但是,在运行时,打印"Called b".
我预计会发生两件事之一.程序将从标准输入中读取一个字符,否则代码将无法编译,因为编译器发现我的运算符和标准库定义的运算符不明确.根据我的理解,标准库定义的运算符相当于:
std::istream &operator>>( std::istream &stream, char &c )
Run Code Online (Sandbox Code Playgroud)
无论哪种方式,我都没想到我的操作员会被调用.
更奇怪的是,由于上面提到的含糊不清,以下代码无法编译:
#include <iostream>
void function(char &chr)
{
std::cout<<"1 "<<chr<<"\n";
}
void function(char chr)
{
std::cout<<"2 "<<chr<<"\n";
}
int main()
{
char c='a';
function(c);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
除了使用函数而不是运算符之外,我认为编译器对这两种情况的决定没有任何区别.
注意:我完全意识到标准库定义的内容与我上面编写的原型不完全相同.我认为,在解决功能时,至少在这个用例中,重要的是没有区别.请记住,std定义不能有默认参数,因为这是一个运算符重载.
另外,正如我在问题的开头写的那样,我已经知道如何使代码做正确的事情.使用"const char&"而不是"char"定义我的运算符会导致编译器选择正确的重载.
请考虑以下代码:
class a {
public:
int a;
};
void func1( a &&var1 );
void func2( a &&var2 )
{
func1(var2);
}
Run Code Online (Sandbox Code Playgroud)
在尝试编译它时,gcc返回以下内容:
question.cpp: In function ‘void func2(a&&)’:
question.cpp:10:14: error: cannot bind ‘a’ lvalue to ‘a&&’
func1(var);
^
question.cpp:6:6: error: initializing argument 1 of ‘void func1(a&&)’
void func1( a &&var );
^
Run Code Online (Sandbox Code Playgroud)
似乎var2是一个左值,尽管它被明确定义为右值引用.一旦分配,双&符号是否会失去意义?在这里工作的机制是什么?
请考虑以下C++程序:
int _Z5func2v;
void func2() {
}
Run Code Online (Sandbox Code Playgroud)
当您尝试编译它时,它会失败:
$ g++ test.cpp -c
/tmp/cc1RDxpU.s: Assembler messages:
/tmp/cc1RDxpU.s:13: Error: symbol `_Z5func2v' is already defined
/tmp/cc1RDxpU.s: Error: .size expression for _Z5func2v does not evaluate to a constant
Run Code Online (Sandbox Code Playgroud)
这是因为程序定义了一个全局变量,该变量与名称重整后的函数名称相同.
我可以想到很多方法可以解决这个问题,其中最简单的方法是在错位名称的开头使用两个下划线(两个下划线保留用于私有实现).
问题是:为什么选择的方案可以实现?
immutable auto a = Array!int([1, 2, 3]);
Run Code Online (Sandbox Code Playgroud)
错误:无法隐式转换表达式(((Array!int __slArray2557 = Array(RefCounted(RefCountedStore(null)));),_ _ slArray2557).this([1,2,3]))类型为Array!int to immutable(Array !INT)
通常我只是想在运行时创建一些对象,初始化它然后使它不可变但是如果我尝试这样做,我从上面得到错误.
似乎我可以将一个可变对象强制转换为一个不可变对象
immutable auto a = cast(immutable Array!int) Array!int([1, 2, 3]);
Run Code Online (Sandbox Code Playgroud)
为什么我要把它投到immutable?
铸就不变甚至合法吗?
我正在讲述C的历史,并希望展示一些过去不可能的习语,但现在(特别是在块的中间定义变量).我想表明较旧的C编译器不会编译它.
gcc可以-std=选择设置语言标准.不幸的是,设置它-std=c89不会在块中间定义变量时产生编译错误.
我希望有一个更准确的标准版本(即 - -std=knr),但我找不到任何这样的选项.
我错过了什么吗?这是GCC中的错误吗?
gcc (Ubuntu 8.2.0-7ubuntu1) 8.2.0
Run Code Online (Sandbox Code Playgroud)
错误编译的代码:
#include <stdio.h>
int main(argc, argv)
int argc;
char *argv[];
{
printf("Hello, world\n");
int a;
return 0;
}
Run Code Online (Sandbox Code Playgroud) 我在电子书中读到waitpid(-1,&status,WNOHANG)应该放在while循环中,这样如果多个子进程同时退出,它们都会被收获.
我通过同时创建和终止2个子进程并通过waitpid收到它而不使用循环来尝试这个概念.这些都被收获了.
问题是,将waitpid放在循环中是否非常必要?
#include<stdio.h>
#include<sys/wait.h>
#include<signal.h>
int func(int pid)
{
if(pid < 0)
return 0;
func(pid - 1);
}
void sighand(int sig)
{
int i=45;
int stat, pid;
printf("Signal caught\n");
//while( (
pid = waitpid(-1, &stat, WNOHANG);
//) > 0){
printf("Reaped process %d----%d\n", pid, stat);
func(pid);
}
int main()
{
int i;
signal(SIGCHLD, sighand);
pid_t child_id;
if( (child_id=fork()) == 0 ) //child process
{
printf("Child ID %d\n",getpid());
printf("child exiting ...\n");
}
else
{
if( (child_id=fork()) == 0 ) //child process …Run Code Online (Sandbox Code Playgroud) epoll在边缘触发模式下是一只奇怪的野兽。它要求该过程跟踪每个受监控FD的最后响应是什么。它要求流程能够无故障地处理所报告的每个事件(否则,我们可能会认为FD实际上没有被边缘触发行为所静音,而是没有报告任何东西)。
什么时候使用epoll这种方式有意义?