返回对特定大小的数组的引用,而不显式返回返回类型

时间:2017-09-14 15:11:17

标签: c++ c++11 c++14 return-type

我有以下功能:

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

我希望将其返回类型设为int(&)[3],但不要明确指定大小(3)。

我该怎么做?

(请不要问为什么我想要那个。)

UPD

好吧,我需要将结果传递给模板函数,并将int(&x)[N]作为参数(我不想将大小明确地传递给该模板函数),所以我看不到返回一对的解决方案如何运作......

5 个答案:

答案 0 :(得分:18)

在C ++ 14中:

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

另外,请考虑使用std::array而不是C风格的数组。

我目前无法想到任何符合标准的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]>{});
}

答案 1 :(得分:3)

需要可用的大小作为编译时常量吗?我建议使用df['NewCol2'] = np.tile(abc, len(df)/len(abc)) df a NewCol NewCol2 0 0 4 4 1 1 4 5 2 2 5 6 3 3 5 4 4 4 6 5 5 5 6 6 (或自己动手)。这基本上只是一个指针和大小,它满足范围概念:

gsl::span

答案 2 :(得分:2)

C ++ 11

另一个C ++ 11替代方案(解决方法),如果你的理论场景(不问为什么......)允许将static数组包装为其他无状态类型的(文字)静态数据成员: / p>

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 */
}

答案 3 :(得分:0)

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

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

    return (x);
}

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

答案 4 :(得分:-1)

因为我使用了很多C ++模板,所以已经有一段时间了。那就是说......

如果总是从N已经可用作模板参数的上下文中调用函数,那么可以将数组大小指定为模板参数吗?

template <int N>
auto getX()->int[N]    {
    static int x[] = {1, 2, 3};
    return x;
}

然后将其传递给用户函数getX<N>,其中N有望已经可用。