我可以理解您愿意使用const而不是constexpr。但有一种更好的方法来创建比什么都没有的constexpr静态成员,它使用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
函数,它接受一个 C 风格的 char
数组,并返回一个 fakeString
。它使用了一个辅助函数 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;
请注意,您需要调用返回C风格字符串的
data()
方法,该字符串是
char *
类型的。请注意,这只是为了好玩。
以下是一个完整的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;
}
std::vector<std::string>
不符合LiteralType的要求。 - R Sahustd::vector
(或std::string
)没有constexpr
构造函数,因此我看不到初始化constexpr std::vector<std::string>
的方法。 - max66vector
和string
包含的数据只能在运行时动态分配,无法在编译时分配。 - Remy Lebeau