C++ 参数不能初始化

C++ 参数不能初始化,c++,compilation,C++,Compilation,是否可以将编译器级别的约束添加到函数参数中,这些参数必须尚未初始化,例如,可以执行以下操作: void f(SomeClass& a) { /* ... */ } int main() { f(new SomeClass()); return 0; } 但以下情况不正常:(因为a已初始化并存储在变量中) 字里行间的阅读,是允许的目标 f(g()); 其中SomeClass g()返回类型为SomeClass的对象 不允许 SomeClass a; f(a); 如果

是否可以将编译器级别的约束添加到函数参数中,这些参数必须尚未初始化,例如,可以执行以下操作:

void f(SomeClass& a) { /* ... */ }

int main() {
    f(new SomeClass());
    return 0;
}
但以下情况不正常:(因为
a
已初始化并存储在变量中)


字里行间的阅读,是允许的目标

f(g());
其中
SomeClass g()
返回类型为
SomeClass
的对象

不允许

SomeClass a;
f(a);
如果是这样,那么您将看到右值引用:

void f(SomeClass&& arg);      // argument is rvalue reference
void f(const SomeClass& arg); // argument is lvalue reference

f(g()); // calls f(SomeClass&&)
SomeClass a;
f(a);   // calls f(SomeClass&)
这可以被故意击败:

f(std::move(a)); // calls f(SomeClass&&)

关于
*
&
有一个考虑因素。 它们不一样。 函数
newsomeclass()
返回一个与
SomeClass&
不同的值
SomeClass*
。 因此,您的代码将无法编译,因为没有可用的隐式转换

为您的代码考虑一种新的结构,如:

void f(SomeClass* a) { /* ... */ }

int main() {
SomeClass* a = new SomeClass();
    f(a);
    return 0;
}

唯一的方法是使用“未初始化”对象(或者是内存,因为对象使用构造函数调用来初始化它),它是编写易于接近C的错误倾向代码,而不是C++。这是因为C++类型的系统试图让你远离未初始化的对象。 如果你真的想沿着这条路走下去,你需要

malloc
一个合适的内存块,然后把它传递给
f
,然后用它来初始化内存中的对象。理论上,您可以将其封装在另一个具有这些语义的类中

与此相关的是,有些标准容器可能在某种程度上满足您的需求,但没有一个容器具有保存“未初始化”对象的主要语义/目的:

  • std::unique\u ptr

    void f(std::unique_ptr<SomeClass>& a) { assert(!a); /* Initialize a... */ }
    
    std::unique_ptr<SomeClass> a; // a is empty
    f(a);
    

您的问题基于错误的前提<代码>f(新的SomeClass())在许多级别上都是错误的。由
new
生成的指针被初始化,而不是一个在堆上分配,另一个在堆栈上。您的两个变量是相同的,都是初始化的。听起来您应该忘记
new
,开始查看右值引用和移动语义。
new SomeClass()
返回类型为
SomeClass*
,而不是
SomeClass&
,并且由于两者之间不可能进行转换,因此此类代码无法编译。除此之外,它还以与
SomeClass a
相同的方式初始化对象本身。只有存储位置/持续时间不同。您真正想要实现的是什么?为什么传递左值会成为一个问题?
void f(std::unique_ptr<SomeClass>& a) { assert(!a); /* Initialize a... */ }

std::unique_ptr<SomeClass> a; // a is empty
f(a);
void f(std::optional<SomeClass>& a) { assert(!a.has_value()); /* Initialize a... */ }

std::optional<SomeClass> a; // a is empty
f(a);