C++ 区分按参考传递和按值传递

C++ 区分按参考传递和按值传递,c++,reference,return-value,ambiguity,C++,Reference,Return Value,Ambiguity,通过引用传递函数与通过值传递函数的典型区别是什么?例如: template <typename T> void sort(std::vector<T>& source); // Sorts source. // Versus... template <typename T> std::vector<T> sort(std::vector<T> source); // Returns a sorted copy of sour

通过引用传递函数与通过值传递函数的典型区别是什么?例如:

template <typename T>
void sort(std::vector<T>& source); // Sorts source.

// Versus...

template <typename T>
std::vector<T> sort(std::vector<T> source); // Returns a sorted copy of source.
模板
空排序(标准::向量和源);//分类来源。
//对。。。
模板
std::向量排序(std::向量源);//返回源的已排序副本。
这两个功能不明确;其中一个必须重命名或完全删除


如何避免这种情况?一种形式应该优先于另一种形式吗?或者有什么共同的命名准则来区分它们吗?

你不能给它们起不同的名字吗?例如,我会将功能版本命名为已排序的


仅仅因为您可以重载函数(或者在这种情况下重载函数模板),并不意味着您必须这样做

顺便说一下,您可以根据“命令式版本”实现“功能性版本”:

模板
无效排序(标准::向量和源)
{
//分类到位
}
模板
标准::向量排序(标准::向量副本)
{
排序(副本);
返回副本;
}

如果可能,通常最好不要通过非常量引用传递,而使用第二种形式。这是因为,首先,如果您想将返回值传递给另一个函数,那么第二种排序的效果更好;其次,因为编译器的优化器在大多数情况下都会处理不必要的复制;第三,因为在中有一个引用可以防止任何类型的TMP检测到它实际上是一个返回值的事实,并防止在任何类型的函数对象上下文中使用该函数。

一针见血。但是,要回答您的问题“或者是否有任何共同的命名准则来区分它们?”只需确保您是一致的。例如,示例中第二个函数名的SortCopy。不管是SortCopy,SortCopy,Sort\u Copy。。重要的是,在整个代码中,您都是一致的(例如,所有作用于副本的函数都有“copy”前缀,而不是一个有副本、下一个Cpy等等)。

“仅仅因为您可以重载并不意味着您应该”是黄金。为什么这是一个需要解决的问题?由于它们是不明确的,编译器将不允许它们共存,因此问题只会持续运行编译器所需的时间,然后程序员将撤消以前的更改。这是一个关于函数签名的问题。如果第二个声明经过
const
reference,编译器可以区分签名。调用时真的不可能区分OP问题中的两个函数吗?如果是的话,如果C++编译器即使没有调用函数也会出错,那么它怎么会稍微好一些呢?我可以用GC++版本4.63.没有调用。+代码:>代码/ >代码> STD::代码> STD::代码> > />代码:STD::ReaveWiSopyIf():BooDo.<代码> Boo::toOxLoR()<代码> >代码> Boo::To-LoeLaScript()/<代码> @ GMMA:不是我的投票,而是1)“防止在任何类型的函数对象上下文中使用该函数”是错误的(例如std::for_each),2)名为sort的函数(例如std::sort,boost::sort)的典型用法是引用语义而不是值语义,3)只是没有解决问题,支持模糊的、通用的建议,这与“sort”相反“公约。似乎这应该是一个评论。
template <typename T>
void sort(std::vector<T>& source)
{
    // sort in place
}

template <typename T>
std::vector<T> sorted(std::vector<T> copy)
{
    sort(copy);
    return copy;
}