我正在尝试在我的类 Foo
中初始化 std::string
的 static constexpr std::vector
。稍后我将使用其元素的地址。
class Foo {
public:
static constexpr std::vector<std::string> a = {"a", "bc", "232"}; // not working, constexpr variable not literal ....
const std::vector<std::string> a = {"a", "bc", "232"}; // this works
}
使用 c++11,谢谢。
最佳答案
I can live with const instead of constexpr. but it's a little bit odd that there's no way to do this
很高兴你能忍受const
但是,为了好玩,我向您展示了一种创造胜于无的方法 constexpr
static
使用 std::array
的成员而不是 std::vector
和(再次)std::array
而不是 std::string
.
很遗憾,您使用的是 C++11,所以没有 std::index_sequence
/std::make_index_sequence
(从 C++14 开始可用)但我在以下完整示例中添加了 C++11 替代品。
如果您知道要在 constexpr
中使用的字符串长度的上限成员,比如说 9(在你的例子中是 3),你可以定义一个 fakeString
输入如下
using fakeString = std::array<char, 10u>;
观察 std::array
的大小是最大长度加一(加上最后的零)。
现在你可以定义foo
如下
struct foo
{
static constexpr std::array<fakeString, 3u> a
{{ fs("a"), fs("bc"), fs("232") }};
};
constexpr std::array<fakeString, 3u> foo::a;
哪里fs()
是 constexpr
返回 fakeString
的函数给定一个 C 风格数组 char
并使用 fsh()
辅助函数
fs()
和 fsh()
功能如下
template <std::size_t ... Is, std::size_t N>
constexpr fakeString fsh (indexSequence<Is...> const &, char const (&s)[N])
{ return {{ s[Is]... }}; }
template <std::size_t N>
constexpr fakeString fs (char const (&s)[N])
{ return fsh(makeIndexSequence<N>{}, s); }
现在您可以使用 foo::a
如下
for ( auto const & fakeS : foo::a )
std::cout << fakeS.data() << std::endl;
请注意,您必须调用 data()
返回 char *
的方法, 那是一个 C 风格的字符串。
我重复一遍:只是为了好玩。
下面是一个完整的编译C++11的例子
#include <array>
#include <iostream>
template <std::size_t...>
struct indexSequence
{ using type = indexSequence; };
template <typename, typename>
struct concatSequences;
template <std::size_t... S1, std::size_t... S2>
struct concatSequences<indexSequence<S1...>, indexSequence<S2...>>
: public indexSequence<S1..., ( sizeof...(S1) + S2 )...>
{ };
template <std::size_t N>
struct makeIndexSequenceH
: public concatSequences<
typename makeIndexSequenceH<(N>>1)>::type,
typename makeIndexSequenceH<N-(N>>1)>::type>::type
{ };
template<>
struct makeIndexSequenceH<0> : public indexSequence<>
{ };
template<>
struct makeIndexSequenceH<1> : public indexSequence<0>
{ };
template <std::size_t N>
using makeIndexSequence = typename makeIndexSequenceH<N>::type;
using fakeString = std::array<char, 10u>;
template <std::size_t ... Is, std::size_t N>
constexpr fakeString fsh (indexSequence<Is...> const &, char const (&s)[N])
{ return {{ s[Is]... }}; }
template <std::size_t N>
constexpr fakeString fs (char const (&s)[N])
{ return fsh(makeIndexSequence<N>{}, s); }
struct foo
{
static constexpr std::array<fakeString, 3u> a
{{ fs("a"), fs("bc"), fs("232") }};
};
constexpr std::array<fakeString, 3u> foo::a;
int main ()
{
for ( auto const & fakeS : foo::a )
std::cout << fakeS.data() << std::endl;
}
关于c++ - 如何在 C++11 中初始化 std::vector<std::string> 的静态 constexpr 成员?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52264304/