使用boost :: ref表示编码约定的意图

时间:2012-11-01 22:38:22

标签: c++ boost coding-style conventions ref

当函数将非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));

这将用作公司编码惯例。 我的问题是,有什么理由说这不是一个好主意吗?

2 个答案:

答案 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不一样......