Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/160.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何区分C++;?_C++_Class_Oop_Constructor_Explicit - Fatal编程技术网

C++ 如何区分C++;?

C++ 如何区分C++;?,c++,class,oop,constructor,explicit,C++,Class,Oop,Constructor,Explicit,我试图检测何时调用了显式构造函数调用,何时调用了隐式构造函数调用 假设我们有一个类Foo: class Foo{ public: Foo(int _val) : val(_val){}; private: int val; } void bar(Foo f){ ... } 我们可以这样称呼酒吧: Foo f(10); bar(f); 或者说: bar(10); // implicit initialization 现在,我知道,如果我们让ctor明确化: class

我试图检测何时调用了显式构造函数调用,何时调用了隐式构造函数调用

假设我们有一个类
Foo

class Foo{
public:
    Foo(int _val) : val(_val){};
private:
    int val;
}

void bar(Foo f){
   ...
}
我们可以这样称呼酒吧:

Foo f(10);
bar(f);
或者说:

bar(10); // implicit initialization
现在,我知道,如果我们让ctor明确化:

class Foo{
public:
    explicit Foo(int _val) : val(_val){};
private:
    int val;
}
然后我们可以得到这个错误:

bar(10); // ERROR! implicit initialization not allowed.
所以我想也许有一种解决方法可以检测显式调用和隐式调用,如下所示:

class Foo{
public:
    explicit Foo(int _val) : val(_val){}; // calling Foo f(10); bar(f);
    Foo(int _val) : val(_val){}; // calling bar(10);
private:
    int val;
}
但正如所料,它返回“不能重载”,因为函数签名是不明确的

最终结果应该是:

class Foo{
public:
    explicit Foo(int _val) : val(_val), flag(true) {}; // calling Foo f(10); bar(f);
    Foo(int _val) : val(_val), flag(false) {}; // calling bar(10);
private:
    int val;
    bool flag;
}

void bar(Foo f){
    std::cout << "f's flag set to : " << f.flag << std::endl;
}

Foo f(10);
bar(f); // f's flag set to : 1
bar(10); // f's flag set to : 0
class-Foo{
公众:
显式Foo(int _val):val(_val),flag(true){};//调用Foo f(10);bar(f);
Foo(int _val):val(_val),flag(false){};//调用条(10);
私人:
int-val;
布尔旗;
}
空栏(Foo-f){
标准::cout
所以我想也许有一种解决方法可以检测显式调用和隐式调用,如下所示:

class Foo{
public:
    explicit Foo(int _val) : val(_val){}; // calling Foo f(10); bar(f);
    Foo(int _val) : val(_val){}; // calling bar(10);
private:
    int val;
}
不,这是不可能的。如果这纯粹是出于好奇,那么你有你的答案。如果你正在努力克服一个真正的问题,你可能想发布真正的问题

在C++中,甚至可以这样做:

没有

正如您所看到的,重载歧义是一个问题,这使得您无法知道是调用了隐式构造函数还是显式构造函数

有人可能会假设,在您的情况下,通过留意显式构造函数所需的副本(与隐式构造函数相反),可以知道调用了哪个构造函数,但这并不太可靠,因为一个好的编译器可以利用并绕过复制操作

因此,如果我们依靠复制假设来确定是否调用了显式构造函数,我们可能会收到一个假阴性,以防复制被实际省略


一般来说,复制构造函数是可以省略的,它们不应该有副作用。

这很容易,但解决方案是在调用的函数中,而不是在创建的对象中

void bar(Foo&) { ... }
void bar(Foo&&) { ... }

Foo f(10);
bar(f);  // calls the first one
bar(10); // calls the second one

你为什么认为你需要这样做?这听起来很像一个问题。如果你需要检测到这一点,你的模型有些地方是非常错误的。我不是问是否应该这样做,我是问是否可以这样做。这不是我需要走到我想要的地方的必经之路。在你目前的情况下,你可以区分,作为显式构造r也会做一个复制,而隐式不会做额外的复制。顺便说一句,在你的评论中,“标志设置为1”放错了位置,它应该用于
f(10)
。回答得好,我被copy-elison参数说服了:)我投了赞成票。
bar(Foo(42));
调用第二个。@Jarod42--是的,但这不是问题中的一个例子。这是一个固有的模糊问题,因为它的真正目标没有说明。其中一条评论指出,实际目标是捕捉右值,而不是隐式构造,在这种情况下,这种方法确实解决了这个问题。实际上,这也是一个很好的答案很有趣,因为这是我的“后备计划”。我本来打算用右值和引用重载函数。但是,这确实有一个缺点,就是有2^n多个重载,其中n是Foo输入的#。对于普通的二元/一元运算符,这并不可怕。我的mind@OneRaynyDay--的确,在标准库中,我们对右值和左值的加载都过多。@PeteBe哇,你写了标准图书馆?很荣幸能在你面前:P