首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >返回对特定大小数组的引用,而不显式声明返回类型中的大小。

返回对特定大小数组的引用,而不显式声明返回类型中的大小。
EN

Stack Overflow用户
提问于 2017-09-14 15:11:17
回答 4查看 1.3K关注 0票数 15

我有以下功能:

代码语言:javascript
运行
复制
... getX()
{
    static int x[] = {1, 2, 3};
    return x;
}

我希望它的返回类型为int(&)[3],但不要显式地指定大小(3)。

我该怎么做?

(请不要问我为什么要那样做。)

UPD

好的,我需要将一个结果传递给一个以int(&x)[N]为参数的模板函数(我不想将大小显式地传递给该模板函数),所以我不知道返回一对的解决方案如何工作……

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2017-09-14 15:12:05

在C++14中:

代码语言:javascript
运行
复制
auto& getX()
{
    static int x[] = {1, 2, 3};
    return x;
}

另外,考虑使用std::array而不是C样式的数组。

目前我想不出任何符合标准的C++11解决方案.这里有一个使用复合文本的方法,假设您的目标是不重复元素并推导出对数组的引用:

代码语言:javascript
运行
复制
#include <type_traits>

#define ITEMS 1, 2, 3
auto getX() -> decltype((int[]){ITEMS})
{
    static int x[] = {ITEMS};
    return x;
}
#undef ITEMS

int main()
{
    static_assert(std::is_same<decltype(getX()), int(&)[3]>{});
}
票数 18
EN

Stack Overflow用户

发布于 2017-09-14 15:37:45

是否需要可作为编译时常量的大小?我建议使用gsl::span (或者使用自己的)。这基本上只是一个指针和一个大小,满足范围的概念:

代码语言:javascript
运行
复制
gsl::span<int> getX()
{
    static int x[] = {1, 2, 3};
    return x;
}
票数 3
EN

Stack Overflow用户

发布于 2017-09-14 20:25:59

C++11

另一种C++11替代方案(解决办法),以防您的理论场景(而不是问为什么.)允许将static数组包装为其他无状态类型的(文字)静态数据成员:

代码语言:javascript
运行
复制
class Foo
{
    static constexpr int x[] = {1, 2, 3};
    // delete ctor(s) ...
public:
    static auto getX() -> std::add_lvalue_reference<decltype(x)>::type { return x; }
};
constexpr int Foo::x[];

或者,例如。

代码语言:javascript
运行
复制
class Foo
{
    template <typename T, std::size_t n>
    static constexpr std::size_t array_size(const T (&)[n]) { return n; }

    static constexpr int x[] = {1, 2, 3};

    // delete ctor(s) ...
public:
    template<std::size_t N = array_size(x)>
    static const int (&getX())[N] { return x; }
};
constexpr int Foo::x[];

以上两种方法中的任何一种都适用于您在问题中描述的用例:

代码语言:javascript
运行
复制
template <std::size_t N>
void feedX(const int (&x)[N])
{
    for (const auto num: x) { std::cout << num << "\n"; }    
} 

int main()
{
    feedX(Foo::getX()); /* 1
                           2
                           3 */
}

不过,如果您的理论场景需要对静态数据进行变异,这不会对您有所帮助。您可以将上面的内容调整为允许发生变异的场景,但代价是必须在声明时指定x的大小,因为此时不能(常量-)初始化和推导大小,而且我认为,这种大小的明确性首先是您想要避免的。总之,为了完整起见:

代码语言:javascript
运行
复制
class Foo
{
    static int x[3];
public:
    static auto getX() -> std::add_lvalue_reference<decltype(x)>::type { return x; }
};
int Foo::x[] = {1, 2, 3};

template <std::size_t N>
void feedAndMutateX(int (&x)[N])
{
    for (auto& num: x) { std::cout << num++ << "\n"; }    
} 

int main()
{
    feedAndMutateX(Foo::getX()); /* 1
                                    2
                                    3 */
    feedAndMutateX(Foo::getX()); /* 2
                                    3
                                    4 */
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46222699

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档