当函数将非const ref作为参数时,它可以创建难以读取的代码,因为在调用站点,不明显哪些输入可能会被更改。这导致一些代码约定强制使用指针代替,例如
void func(int input, int* output);
int input = 1, output = 0;
func(input, &output);
而不是
void func(int input, int& output);
int input = 1, output = 0;
func(input, output);
就个人而言,我讨厌使用指针,因为需要检查null。这让我想知道是否可以使用boost :: ref(或者用于C ++ 11的std :: ref)来表示意图,如下所示:
void func(int input, int& output);
int input = 1, output = 0;
func(input, boost::ref(output));
这将用作公司编码惯例。 我的问题是,有什么理由说这不是一个好主意吗?
答案 0 :(得分:3)
这不是一个坏主意,但它并没有真正得到执行(如PiotrNycz所说)。它实际上只是一个评论。
我们可以做得更好:
template <typename T>
class output_argument
{
public:
template <typename U>
friend output_argument<U> out(U& ref);
T& get() const
{
return mRef;
}
operator T&() const
{
return get();
}
private:
explicit output_argument(T& ref) :
mRef(ref)
{}
output_argument& operator=(const output_argument&); // not defined
T& mRef;
};
template <typename U>
output_argument<U> out(U& ref)
{
return output_argument<U>(ref);
}
,并提供:
void foo(int x, output_argument<float> f)
{
int i = static_cast<int>(f);
f.get() = static_cast<float>(i + x);
}
int main()
{
float f = 5.0f;
//fails: foo(1, f);
foo(1, out(f));
}
但通常这些类型的实用程序不是必需的,因为函数名称应该传达参数发生的事情:swap(x, y)
非常清楚地修改参数!返回值应该使用返回类型完成,这进一步限制了可以使用此实用程序的情况。
答案 1 :(得分:1)
这个公司编码惯例可能很容易(当然是错误地)打破了这样:
void func(int input, int& output);
int input = 1, output = 0;
func(boost::ref(input), output);
这编译并且工作正常 - 但却误导读者。
最好是让func具有良好的名称,建议在其中修改一些参数:
void copyTo(int input, int& output);
在现代IDE中 - 您可以在阅读功能正在进行的操作时看到。
通过使用boost :: cref:
,也许更好的公司编码约定会相反void func(int input, int& output);
int input = 1, output = 0;
func(boost::cref(input), output);
这里的错误与boost :: ref不一样......