鉴于代码:
template<typename T>
void foo(const T){}
当我执行以下操作时幕后实际发生的事情:
int main(){
string a;
string* pA = &a;
foo(string("test"));
foo(ref(A));
foo(pA);
return 0;
}
foo
是否获得const
这些对象的副本?或者foo
现在引用此对象但不能更改内容?
答案 0 :(得分:1)
foo
是否会获得const
这些对象的副本?
是。在前两种情况下,它是字符串a
的副本;在第三个中,它是指针pA
的副本。
或
foo
现在引用此对象但无法更改内容?
没有。如果你想要它参考,你会声明它
template <typename T> // note: lower-case "typename"
void foo(const T&){}
^
或指定模板参数的引用类型,而不是让编译器推导出非引用
foo<string&>(a); // or <const string&> for const enforcement
或者,正如您在评论中提到的那样,传递一个引用包装器
foo(std::ref(a)); // or std::cref for const enforcement
答案 1 :(得分:1)
当您的函数按值获取参数时,它会获得一个副本。保持不会发挥作用。
foo(string("test"))
在这种情况下,会创建一个临时对象。如果您的编译器应用Return Value Optimization,则将创建参数的值&#34;就位#34;。换句话说,只有构造函数调用std::string("test")
,而不是构造函数调用,后跟复制构造函数调用,后跟对临时函数的析构函数调用。
foo(rA);
在这种情况下,将使用复制构造函数创建新的std::string
,复制a
作为参考的rA
内容。
foo(ref(A));
在这种情况下,会创建std::reference_wrapper<std::string>
的临时实例。同样,返回值优化将确保它就地创建,而不是复制。
foo(pA);
在这种情况下,指针的复制方式与指针在按值传递时的复制方式相同。指针的值不会改变(demo)。