首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >用另一个的内容和额外的元素初始化一个C++ (11) std::vector

用另一个的内容和额外的元素初始化一个C++ (11) std::vector
EN

Stack Overflow用户
提问于 2015-03-10 20:34:07
回答 5查看 2.5K关注 0票数 17

我需要一种“优雅”的方式,在声明阶段用另一个向量的内容和一些额外的元素来初始化一个向量。

我想解决的是:

让我们考虑以下(示例)带有初始化的声明:

const std::vector<std::string> c90_types = {
    "char",
    "signed char",
    "unsigned char",
    "short",
    "unsigned short",
    "int",
    "unsigned int",
    "long",
    "unsigned long",
    "float",
    "double",
    "long double"
};

const std::vector<std::string> c99_types = {
    "char",
    "signed char",
    "unsigned char",
    "short",
    "unsigned short",
    "int",
    "unsigned int",
    "long",
    "unsigned long",
    "float",
    "double",
    "long double",
    "long long",
    "unsigned long long",
    "intmax_t",
    "uintmax_t"
};

正如您所看到的,c99_types有一个子集,它就是c90_types。我希望避免需要更改子集,然后手动更改“超集”的情况,只是为了避免可能引入错误的额外步骤:)

顺便说一句,我不想写这样的代码:

second.insert(second.begin(), first.begin(), first.end());
second.push_back(something);

有什么好的和干净的解决方案吗?

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2015-03-10 23:08:00

有一个技巧叫做“我想用一些复杂的东西初始化一个常量变量”。这在C++11中成为可能,它是从Javascript中无耻地窃取的。

const std::vector<std::string> c90_types = {
    "char",
    // and so on, and so forth....
};

const std::vector<std::string> c99_types = ([&](){
    const auto additional_types = { // initializer_list<const char *>, but it does not matter.
        "long long",
        "unsigned long long",
        "intmax_t",
        "uintmax_t"
    };

    std::vector<std::string> vec{c90_types};

    vec.insert(vec.end(), additional_types.begin(), additional_types.end());

    return vec;
})();

将您的初始化逻辑打包到一个未命名的lambda中,并立即调用它,复制初始化您的常量变量。

vec被移动,而不是复制。

票数 18
EN

Stack Overflow用户

发布于 2015-03-10 20:46:36

您可以首先定义最大的向量(这里是c99_types),然后用最大的一个迭代器构造其他的向量。

下面是一个示例:

const vector<int> a{1,2,3,4};
const vector<int> b{begin(a), begin(a)+2}; // b is {1,2}

所以你可以这样写:

const std::vector<std::string> c99_types = {
    "char",
    "signed char",
    "unsigned char",
    "short",
    "unsigned short",
    "int",
    "unsigned int",
    "long",
    "unsigned long",
    "float",
    "double",
    "long double",
    "long long",
    "unsigned long long",
    "intmax_t",
    "uintmax_t"
};

const std::vector<std::string> c90_types{begin(c99_types), begin(c99_types)+12};
票数 7
EN

Stack Overflow用户

发布于 2015-03-10 21:34:21

选项1:std::array

这可能可以清理和改进很多,但它至少是一个起点(它使用Jonathan Wakely's redi::index_tuple

template<typename T, std::size_t N, unsigned... I, typename ...U>
inline auto
append_array_helper(const std::array<T, N>& array, redi::index_tuple<I...>, U&&... elements) -> std::array<T, N + sizeof...(elements)>
{
    return std::array<T, N + sizeof...(elements)>{ std::get<I>(array)..., std::forward<U>(elements)... };
}

template<typename T, std::size_t N, typename ...U>
inline auto
append_array(const std::array<T, N>& array, U&&... elements) -> std::array<T, N + sizeof...(elements)>
{
    return append_array_helper(array, typename redi::make_index_tuple<N>::type(), std::forward<U>(elements)...);
}

const std::array<std::string, 12> c90_types = {
    "char",
    "signed char",
    "unsigned char",
    "short",
    "unsigned short",
    "int",
    "unsigned int",
    "long",
    "unsigned long",
    "float",
    "double",
    "long double"
};

const std::array<std::string, 16> c99_types = append_array(
    c90_types,
    "long long",
    "unsigned long long",
    "intmax_t",
    "uintmax_t"
);

如果您不想指定数组大小,可以使用以下方法:

template<typename T, typename... U>
constexpr auto make_array(U&&... elements) -> std::array<T, sizeof...(elements)>
{
    return { std::forward<U>(elements)... };
}

const auto c90_types = make_array<std::string>(
    "char",
    "signed char",
    "unsigned char",
    "short",
    "unsigned short",
    "int",
    "unsigned int",
    "long",
    "unsigned long",
    "float",
    "double",
    "long double"
);

...

选项2:宏

不是我的最爱,但它很简单,易于理解和编辑:

#define C90_TYPES         \
    "char",               \
    "signed char",        \
    "unsigned char",      \
    "short",              \
    "unsigned short",     \
    "int",                \
    "unsigned int",       \
    "long",               \
    "unsigned long",      \
    "float",              \
    "double",             \
    "long double"

#define C99_TYPES         \
    C90_TYPES,            \
    "long long",          \
    "unsigned long long", \
    "intmax_t",           \
    "uintmax_t"

const std::vector<std::string> c90_types = {
    C90_TYPES
};

const std::vector<std::string> c99_types = {
    C99_TYPES
};
票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28963884

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档