是否重新添加对象/引用/指针以添加const

时间:2014-10-23 13:41:33

标签: c++ parameters const parameter-passing

鉴于代码:

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现在引用此对象但不能更改内容?

2 个答案:

答案 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)。