代码之家  ›  专栏  ›  技术社区  ›  ledonter

返回对特定大小数组的引用,而不在返回类型中明确说明大小

  •  15
  • ledonter  · 技术社区  · 8 年前

    我有以下功能:

    ... getX()
    {
        static int x[] = {1, 2, 3};
        return x;
    }
    

    int(&)[3]

    我该怎么做?

    (请不要问 为什么?

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

    4 回复  |  直到 8 年前
        1
  •  18
  •   Vittorio Romeo    8 年前

    在C++14中:

    auto& getX()
    {
        static int x[] = {1, 2, 3};
        return x;
    }
    

    此外,考虑使用 std::array


    我目前想不出任何符合标准的C++11解决方案。这里有一个使用 复合文字

    #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]>{});
    }
    
        2
  •  3
  •   Barry    8 年前

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

    gsl::span<int> getX()
    {
        static int x[] = {1, 2, 3};
        return x;
    }
    
        3
  •  2
  •   Community Mohan Dere    6 年前

    C++11

    static 数组作为其他无状态类型的(文字)静态数据成员:

    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[];
    

    或者,例如。

    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[];
    

    以上两项中的任何一项适用于您在问题中描述的用例:

    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

    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 */
    }
    
        4
  •  0
  •   StoryTeller - Unslander Monica    8 年前

    如果你真的想要一个参考,并且有C++14,那么 decltype(auto) 带圆括号的id表达式:

    decltype(auto) get_arr() {
        static int x[] = {1, 2 ,3};
    
        return (x);
    }
    

    将推断为对数组的引用 See it live ,其中引用的类型显示在错误消息中。