`const`修饰符和引用在std :: function的模板参数中的作用是什么

时间:2012-03-13 05:54:58

标签: c++ function c++11 const

我不确定const修饰符和引用在std :: function的模板参数中的效果。例如,在以下代码中,我应该使用std::function<bool(std::string, std::string)>还是std::function<bool(const std::string&, const std::string&)>作为基类?我在GCC 4.4中进行了测试,但是没有区别。提前谢谢。

#include <iostream>
#include <functional>
#include <string>

//struct FLess : public std::function<bool(std::string, std::string)>
struct FLess : public std::function<bool(const std::string&, const std::string&)>
{
    bool operator () (const std::string& s1, const std::string& s2) const
    {
        return s1 < s2;
    }
};

int main(int argc, char* argv[])
{
    FLess f;
    std::string a = "a";
    std::string b = "b";
    std::cerr << f(a, b) << std::endl;
    return 0;
}

2 个答案:

答案 0 :(得分:1)

它归结为函数对象的参数类型与它所引用的可调用实体的参数类型之间的兼容性,如果函数的参数类型可以转换为可调用实体参数类型:

void foo(double x, double y);
void bar(const double& x, const double& y);
void fooBar(double& x, double& y);

std::function<void(const double&, const double&)> f;

f = &foo; // OK
f = &bar; // OK
f = &fooBar; // Error on GCC 4.7. Cannot instantiate a double& from const double.

有趣的是,具有void返回类型的std :: function与具有任何返回类型的可调用实体兼容:

int fooBarFoo(const double& x, const double& y);

f = &fooBarFoo; // OK

所以在你的情况下,你比较传递const引用而不是传递值,我认为没有可观察到的差异。

答案 1 :(得分:0)

传递对const对象的引用可以避免将对象的副本传递给函数。在你的情况下(一个很小的字符串),它可能没有足够的区别来注意。

如果你正在处理一些(例如)几兆字节的字符串,那么通过引用const来避免为所有数据分配空间(并复制)。

与此同时,大多数编译器在内部实现的引用与指针非常相似。由于额外的间接级别,这可能导致执行速度变慢。对于小项目(char,int,可能很长),您通常更喜欢传递值。对于较大的项目(可能是长字符串,矩阵等),您通常更喜欢通过引用传递。如果有疑问,通常以参考方式传递 - 在这个方向上的错误处罚通常相当小。