【问题标题】:Declare std::array member variable's size based on constructor string literal根据构造函数字符串文字声明 std::array 成员变量的大小
【发布时间】:2020-10-01 14:42:00
【问题描述】:

我需要一个将编译时字符串文字 (const char* const) 作为其唯一构造函数参数的类。

我想要一个 std::array 成员变量将单词存储在这个字符串文字中(例如,使用空格分割)。因此这个数组的大小永远不会改变,因为字符串字面量在编译时是已知的。

如何将这个数组作为成员变量,同时通过传入构造函数的字数指定其大小?

我想让调用者不需要在类模板参数中指定字数,但构造函数(可能是 constexpr 的)可以在编译时推断出这一点。

我不想使用向量,因为在这种情况下没有必要(存储的单词永远不会改变)。我该怎么办?

谢谢

【问题讨论】:

  • 你需要展示你到目前为止所做的事情以及你遇到错误的地方。
  • 我没有做太多,因为我不知道从哪里开始......我刚刚谷歌搜索但无济于事。
  • 你不能这样做。如果您在定义类时不知道大小,则必须使用向量或将类本身作为模板,然后将大小传递给。
  • 如果您想将此字符串传递给构造函数,则不是。为了定义类本身,比如struct foo { std::array<char, some_size> };,你必须知道some_size。您无法在构造函数中更改类的大小,因此无法将其传递给构造函数。
  • 字符串文字不是const char*s;他们是const char[N]s。

标签: c++ templates constexpr


【解决方案1】:

首先,你必须使用类模板,因为不同的字符串字面量应该有不同的类大小。模板参数至少应包含封闭数组的大小(例如template<std::size_t N>)。

然后您可能会发现 C++17 中的类模板参数推导很有用,因此您不必自动指定大小。您可以使用构造函数的自动扣除或提供自定义扣除指南。如果你没有 C++17,你可以创建一个类似于make_pair/make_tuple 的辅助函数,它将使用模板参数推导并创建相应的类。

#include <algorithm>
#include <array>
#include <cstddef>
#include <iterator>
#include <iostream>

template<std::size_t N>
struct WordStorage {
    std::array<char, N> char_array;
    WordStorage(const char (&char_array_)[N]) {
        std::copy(char_array_, char_array_ + N, char_array.begin());
    }
};

int main() {
    WordStorage s("hello");  // Deduced to WordStorage<6> as "hello" is const char[6].
    static_assert(s.char_array.size() == 6);
    std::cout << s.char_array.data() << "\n";
}

【讨论】:

  • 这似乎是我一直在寻找的答案 - 非常感谢。只是一个问题-我将如何“提供自定义扣除指南”?我快速谷歌搜索并没有太大帮助。你能指出我正确的方向吗?
【解决方案2】:

在我看来可能是你能得到的最接近的东西:


template <char... c>
class foo
{
private:
    std::array<char, sizeof...(c)> m_arr;

public:
    foo()
    {
        std::cout << m_arr.size()<<'\n'; //ok : prints 3
    }
};

int main()
{
    foo<'c', 'h', 'a'> f;
}

【讨论】:

  • 不幸的是,这对我的用例来说非常不切实际:(除非有任何简单的方法可以制作具有相同效果的宏?我最终还需要以某种方式处理传入的字符串并制作数组基于单词的数量,所以这个特定的方法在这方面也不够......嗯。
  • @yeputons 对模板参数推导的回答似乎有效
猜你喜欢
  • 2017-01-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-02-22
  • 2022-11-14
  • 2021-10-31
  • 1970-01-01
相关资源
最近更新 更多