相关疑难解决方法(0)

为什么不将`std :: initializer_list`定义为文字类型?

这是这个问题的后续问题:声明constexpr initializer_list对象是否合法?.

从C++ 14开始,std::initializer_list该类的所有方法都标有constexpr.能够通过执行来初始化实例似乎很自然, constexpr std::initializer_list<int> list = {1, 2, 3}; 但是Clang 3.5抱怨list没有被常量表达式初始化. 正如dyp在评论中指出的那样,任何std::initializer_list文字类型的要求似乎都从规范中消失了.

如果我们甚至不能将类完全定义为constexpr,那么有什么意义呢?这是标准中的疏忽,将来会得到修复吗?

c++ initializer-list language-lawyer constexpr c++14

58
推荐指数
1
解决办法
2635
查看次数

迭代非增量枚举

在你问之前,我已经在SO上寻找寻找了这个,但是找不到可靠的答案.

我需要能够动态迭代具有非增量值的枚举,例如:

typedef enum {
    CAPI_SUBTYPE_NULL = 0,               /* Null subtype. */
    CAPI_SUBTYPE_DIAG_DFD = 1,           /* Data Flow diag. */
    CAPI_SUBTYPE_DIAG_ERD = 2,           /* Entity-Relationship diag. */
    CAPI_SUBTYPE_DIAG_STD = 3,           /* State Transition diag. */
    CAPI_SUBTYPE_DIAG_STC = 4,           /* Structure Chart diag. */
    CAPI_SUBTYPE_DIAG_DSD = 5,           /* Data Structure diag. */
    CAPI_SUBTYPE_SPEC_PROCESS = 6,       /* Process spec. */
    CAPI_SUBTYPE_SPEC_MODULE = 7,        /* Module spec. */
    CAPI_SUBTYPE_SPEC_TERMINATOR = 8,    /* Terminator spec. */

    CAPI_SUBTYPE_DD_ALL = …
Run Code Online (Sandbox Code Playgroud)

c++ enums iterator

38
推荐指数
3
解决办法
1万
查看次数

为什么枚举值的initializer_list不被视为常量表达式?

在以下代码中(在本地和Wandbox上测试):

#include <iostream>

enum Types
{
    A, B, C, D
};

void print(std::initializer_list<Types> types)
{
    for (auto type : types)
    {
        std::cout << type << std::endl;
    }
}

int main()
{
    constexpr auto const group1 = { A, D };
    print(group1);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

MSVC 15.8.5无法编译:

error C2131: expression did not evaluate to a constant
note: failure was caused by a read of a variable outside its lifetime
note: see usage of '$S1'
Run Code Online (Sandbox Code Playgroud)

(均指含有的行constexpr)

Clang 8(HEAD)报道:

error: constexpr …
Run Code Online (Sandbox Code Playgroud)

c++ language-lawyer constexpr c++17

15
推荐指数
2
解决办法
809
查看次数

什么是具有静态存储持续时间的临时对象

灵感来自这个答案,来自[expr.const]

常量表达式是glvalue核心常量表达式,它指的是一个实体,它是常量表达式的允许结果(如下所定义),或者是一个prvalue核心常量表达式,其值满足以下约束:

  • 如果值是类类型的对象,则引用类型的每个非静态数据成员引用一个实体,该实体是常量表达式的允许结果,

  • 如果值是指针类型,则它包含具有静态存储持续时间的对象的地址,超过此类对象末尾的地址([expr.add]),函数的地址或空指针值,以及

  • 如果值是类或数组类型的对象,则每个子对象都满足这些值的约束.

如果实体是具有静态存储持续时间对象,则该实体是常量表达式的允许结果,该对象不是临时对象,或者是其值满足上述约束的临时对象,或者它是函数.

什么是具有静态存储持续时间的临时对象?我是否遗漏了某些东西,或者说对象是暂时的并且具有静态存储持续时间是矛盾的吗?

来自[basic.stc.static]的定义

所有没有动态存储持续时间,没有线程存储持续时间且不是本地的变量都具有静态存储持续时间.这些实体的存储应持续该计划的持续时间

仅适用于变量.

c++ language-lawyer

13
推荐指数
1
解决办法
546
查看次数

查找表与constexpr

我正在寻找创建一个坐标查找表,如:

int a[n][2] = {{0,1},{2,3}, ... }
Run Code Online (Sandbox Code Playgroud)

对于给定的n,在编译时创建.我开始研究constexpr,但似乎是一个函数返回a constexpr std::vector<std::array <int, 2> >不是一个选项,因为我得到:

invalid return type 'std::vector<std::array<int, 2ul> >' of constexpr function
Run Code Online (Sandbox Code Playgroud)

如何创建这样的编译时数组?

c++ constexpr c++11

12
推荐指数
2
解决办法
9153
查看次数

constexprinitializer_list 使用 MSVC 不产生输出

以下程序在 GCC 和 Clang 中编译时不会发出警告,并产生预期的输出:

#include <initializer_list>
#include <iostream>

constexpr std::initializer_list<std::initializer_list<const char*>> list = {
    {"a", "b", "c"},
    {"d"}
};

int main() {
    for (const auto& outer: list) {
        std::cout << "level:\n";
        for (const auto& inner: outer) {
            std::cout << "  " << inner << "\n";
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

然而,使用 MSVC,该程序根本不会产生任何输出。

根据 C++ 标准,该程序有效吗?这是 MSVC 中的错误吗?如果这不是有效的 C++ 那么为什么 GCC 或 Clang 没有发出警告?有没有更好的方法来创建constexpr内部列表没有固定大小的嵌套列表?

c++ language-lawyer stdinitializerlist

11
推荐指数
1
解决办法
215
查看次数

意外的非常量std :: initializer_list

我正在玩索引技巧,看​​看我可以去哪里,并遇到一个奇怪的错误...首先,简单的不那么老的指数:

template<std::size_t...>
struct indices {};

template<std::size_t N, std::size_t... Indices>
struct make_indices:
    make_indices<N-1, N-1, Indices...>
{};

template<std::size_t... Indices>
struct make_indices<0, Indices...>:
    indices<Indices...>
{};
Run Code Online (Sandbox Code Playgroud)

我创建了一个从a派生的编译时数组类std::initializer_list,并使其具有可索引性(假设N3471支持您的编译器.无论如何它将在下一个标准中).这里是:

template<typename T>
struct array:
    public std::initializer_list<T>
{
    constexpr array(std::initializer_list<T> values):
        std::initializer_list<T>(values)
    {}

    constexpr auto operator[](std::size_t n)
        -> T
    {
        return this->begin()[n];
    }
};
Run Code Online (Sandbox Code Playgroud)

所以,我尝试创建一个函数,array在每个成员添加1后返回一个副本:

template<typename T, std::size_t... I>
auto constexpr add_one(const array<T>& a, indices<I...>)
    -> const array<T>
{
    return { (a[I]+1)... };
}
Run Code Online (Sandbox Code Playgroud)

并完成代码,这是我的主要:

int main()
{
    constexpr array<int> a = …
Run Code Online (Sandbox Code Playgroud)

c++ compile-time initializer-list variadic-templates c++11

8
推荐指数
1
解决办法
1266
查看次数