如何初始化std :: vector的静态constexpr成员 在c ++ 11中?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何初始化std :: vector的静态constexpr成员 在c ++ 11中?相关的知识,希望对你有一定的参考价值。
我正在尝试在我的班级static constexpr std::vector
中初始化std::string
的Foo
。我稍后会使用其元素的地址。
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,谢谢。
我可以和const一起使用而不是constexpr。但是有点奇怪,没有办法做到这一点
你可以和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
的大小是max-length加1(加上最后的零)。
现在您可以按如下方式定义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;
}
以上是关于如何初始化std :: vector的静态constexpr成员 在c ++ 11中?的主要内容,如果未能解决你的问题,请参考以下文章
如何在初始化中将 'std::vector<double>' 转换为 'double'