范围保护和参数参考

时间:2011-05-08 14:05:46

标签: c++ raii scopeguard

参考支持参数部分的this文章中,他们指出了问题,并为参考提供了解决方案。我的问题是:为什么他们不首先将参数声明为引用?即,而不是:

const Parm parm_;

做的:

Parm &parm_;

3 个答案:

答案 0 :(得分:0)

必须是

const Param &param_;

允许一般情况,然后你会遇到同样的问题,尝试减少或以其他方式修改参数。另一种选择是创建更多类来处理const和非const版本。

使用引用会阻止将表达式的结果用作参数,因为作为函数参数创建的临时引用会立即超出范围。

虽然他可以删除所有的const并让它成为类型的一部分而不允许表达式,但我认为要求ByRef有助于清晰度仍然有很大的价值。

答案 1 :(得分:0)

有一个问题:在C ++中,临时数不能绑定到引用,而只能绑定到const引用。

因此,不能写下列内容:

int foo();

int& i = foo();

除非你使用Visual C ++,它允许它作为语言的扩展。

另外,如果我使用了一个返回const引用的函数,那么它也不会工作。

这里没有简单的解决方案:)

至少在C ++ 0x lambdas进入图片之前

答案 2 :(得分:0)

因为引用的问题只是如何使用scopeguard的一个例子。但它应该在所有其他情况下工作(并且正常工作)。所以有这个清理功能:

void my_exit(const std::string & msg)
{
    std::cout << "my_exit: " << msg << std::endl;
}

这应该有效(传递临时对象):

void test()
{
    std::string msg("test_1 Hello World");
    ON_BLOCK_EXIT(&my_exit, msg.substr(0, 6));
}

这应该有效(在调用scopeguard之前传递对将被销毁的对象的引用):

void test()
{
    std::map<int, std::string> m;
    m[42] = "test_2";
    ON_BLOCK_EXIT(my_exit, m[42]);

    m.clear();
}

这应该有效(传递一个const引用):

void test(const std::string & msg)
{
    ON_BLOCK_EXIT(&my_exit, msg);
}

如果parm是const或非const引用,那么这些示例在运行时将无法编译或崩溃。