【问题标题】:How to use a cv-qualifier for a method that returns a reference to an array?如何为返回数组引用的方法使用 cv 限定符?
【发布时间】:2016-09-23 03:18:22
【问题描述】:

如果我有一个返回对数组的引用的成员函数 (https://stackoverflow.com/a/5399014/4304120),我如何向该函数添加 const 限定符?此代码无法在 Visual C++ 2010 下编译。

struct A
{
    int data[10];

    // this compiles
    const int (&f1())[10]
    {
        return data;
    }

    // error C2143: syntax error : missing ';' before '<cv-qualifer>'
    const int (&f2())[10] const
    {
        return data;
    }
};

【问题讨论】:

  • 从C++14开始可以避免const auto&amp; f2() const { return data; }的问题

标签: c++


【解决方案1】:

我将提出几个在我看来比对这个问题的极其直接的答案更具可读性的解决方案。我确定那里有 C 语法爱好者,我向他们道歉,因为我的记忆力很差,而且我无法记住那些 C 规则。

输入别名

您可以通过使用类型别名来避免奇怪的基于 C 的语法:

struct A {
    using data_type = int[10];
    data_type data;
    data_type& f1() { return data; }
    data_type const& f2() const { return data; }
};

Live demo

typedef(在 C++11 之前):

struct A {
    typedef int data_type[10];
    data_type data;
    data_type& f1() { return data; }
    data_type const& f2() const { return data; }
};

Live demo

自动

从 C++14 开始,您还可以使用 auto 返回类型:

struct A {
    int data[10];
    auto& f1() { return data; }
    auto const& f2() const { return data; }
};

Live demo

标准数组

从 C++11 开始,您也可以只使用 std::array:

struct A {
    using data_type = std::array<int, 10>;
    data_type data;
    data_type& f1() { return data; }
    data_type const& f2() const { return data; }
};

Live demo

并将其简化为:

struct A {
    std::array<int, 10> data;
};

Live demo

这在功能上有点相同,但对眼睛更容易。

【讨论】:

  • 您的第一个示例中没有缺少 const 吗?
  • @MohamadElghawi 谢谢。
  • 我们不能也使用尾随返回类型来获得一个干净但精确的返回类型吗?
  • 更像auto ... -&gt; int const(&amp;)[10],在这种情况下,您可以完整说明实际的返回类型,但没有嵌套在其中的 awkawrd C 样式函数语法。
  • 这是解决问题的明智方法。
【解决方案2】:
const int (&f2() const )[10]
{
    return data;
}

【讨论】:

  • 引用限定符是否也会出现在函数名和参数列表周围的() 中?
  • @NathanOliver 我的问题是正确的,不,你不能这样做int (const&amp;f2() const )[10]
  • @101010 没有 &amp;&amp;&amp; 在成员函数的末尾,以确定它们是仅左值还是右值函数。
  • @MarianSpanik 你得到了你想要的:)
  • @NathanOliver 是的,他们会在 const 之后和其他任何事情之前进行
【解决方案3】:

使用类型定义。这将使每个人的生活更轻松:

struct A
{
    using Data = int[10];
    Data data;

    Data const& f1()
    {
        return data;
    }

    Data const& f2() const
    {
        return data;
    }
};

std::array&lt;int, 10&gt; 也可以做到这一点:

std::array<int, 10> data;
std::array<int, 10> const& f2() const { return data; }

这是std::array 相对于原始数组的另一个优势。

【讨论】:

    【解决方案4】:

    一个 typedef 可以解决您的问题,并使其更具可读性:

    struct A
    {
        typedef int array_t[10];
    
        ...
    
        const array_t& f2() const
        {
            return data;
        }
    };
    

    【讨论】:

    • 对不起,我的问题拼写错误。我想将限定符添加到函数中,而不是返回值。
    • 虽然是一样的。您可以使用typedef,然后像往常一样在函数后添加const
    • 是的,完全正确。编辑完成
    • 使用 C typedef 只是将一个可读性问题换成另一个问题,因为元素和别名类型在概念上是错误的,并且与所有其他用途相比。使用 C++ using 更好。事实上,这可能是为什么后者被添加到 C++ 中的“教科书”示例。
    • @JDługosz 我认为这里 underscore_d 的意思是 typedef 在用于数组/函数声明时可能会被视为不一致 - typedef int myTypetypedef int arrayType[10] -人们可能会期待typedef int[10] arrayType(我意识到这是有规则的,根据他们的说法,这确实是有道理的,但我认为这就是 underscore_d 的意思)。使用using 指令,确实更直观:using arrayType = int[10];
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-06-30
    • 2015-09-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-29
    • 1970-01-01
    相关资源
    最近更新 更多