标签: c++17

int a = 1,是|| 1一个常数表达式?

N4527 5.20 [expr.const] p5

常量表达式是glvalue核心常量表达式,其值指的是一个实体,它是常量表达式的允许结果(如下定义),或者是一个prvalue核心常量表达式,其值是一个对象,对于该对象及其子对象:

- 引用类型的每个非静态数据成员是指一个实体,它是一个常量表达式的允许结果,和

- 如果对象或子对象是指针类型,则它包含具有静态存储持续时间的对象的地址,超过此类对象的结尾的地址(5.7),函数的地址或空指针值.

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

void foo(){
    int a = 1;
    int b[a || 1]{};//ok in gcc 5.1.0, error in clang 3.8.0
    static_assert(a || 1,"");//ok in gcc 5.1.0, error in clang 3.8.0
    switch(1){
        case a || 1://ok in gcc 5.1.0, error in clang 3.8.0
            ;
        }
}
Run Code Online (Sandbox Code Playgroud)

a || 1一个不变的表达


N4527 5.20 [expr.const] p2

条件表达式e是核心常量表达式,除非根据抽象机器(1.9)的规则评估e将评估以下表达式之一:

(2.7) - 左值 - 右值转换(4.1),除非适用于

(2.7.1) - 整数或枚举类型的非易失性glvalue,它引用具有前面初始化的完整非易失性const对象,用常量表达式初始化,或者

(2.7.2) - 一个非易失性glvalue,引用字符串文字的子对象(2.13.5),或者

(2.7.3) - 一个非易失性glvalue,引用用constexpr定义的非易失性对象,或引用这种对象的不可变子对象,或者

(2.7.4) - …

c++ language-lawyer constant-expression c++17

31
推荐指数
1
解决办法
1743
查看次数

constexpr if和static_assert

P0292R1 constexpr如果包含在内,正在进行 C++ 17.它似乎很有用(并且可以取代SFINAE的使用),但关于static_assert形成不良的评论,假分支中不需要诊断会让我害怕:

Disarming static_assert declarations in the non-taken branch of a
constexpr if is not proposed.

void f() {
  if constexpr (false)
    static_assert(false);   // ill-formed
}

template<class T>
void g() {
  if constexpr (false)
    static_assert(false);   // ill-formed; no 
               // diagnostic required for template definition
}
Run Code Online (Sandbox Code Playgroud)

我认为它是完全禁止static_assert在constexpr内部使用if(至少是假/非分支,但实际上这意味着它不是一个安全或有用的事情).

这是如何从标准文本中产生的?我发现static_assert在提案中没有提到措辞,并且C++ 14 constexpr函数允许static_assert(cppreference的详细信息:constexpr).

是否隐藏在这个新句子中(6.4.1之后)?:

当constexpr if语句出现在模板化实体中时,在封闭模板或通用lambda的实例化期间,不会实例化丢弃的语句.

从那以后,我认为它也是禁止的,不需要诊断,调用调用图中某个地方可能调用的其他constexpr(模板)函数static_assert.

底线:

如果我的理解是正确的,那么对于constexpr …

c++ templates static-assert constexpr c++17

31
推荐指数
4
解决办法
8565
查看次数

__cplusplus对C++ 17的价值是多少?

我们正在尝试在C++ 17下测试一些代码并将其更改为std::uncaught_exception.我似乎无法让GCC提供以下价值__cplusplus:

$ /opt/local/bin/g++ -std=c++17 -dM -E - </dev/null | grep __cplusplus
cc1: warning: command line option '-std=c++1z' is valid for C++/ObjC++ but not for C
$
Run Code Online (Sandbox Code Playgroud)

和:

$ /opt/local/bin/g++ --version
g++-mp-6 (MacPorts gcc6 6.1.0_0) 6.1.0
Copyright (C) 2016 Free Software Foundation, Inc.
Run Code Online (Sandbox Code Playgroud)

__cplusplus使用C++ 17时有什么价值?

c++ macros c++17

31
推荐指数
4
解决办法
2万
查看次数

如何在需要旧式unsigned char的地方使用新的std :: byte类型?

std::byte是C++ 17中的新类型,它是作为enum class byte : unsigned char.如果没有适当的转换,这将无法使用它.所以,我为这种类型的向量做了一个别名来表示一个字节数组:

using Bytes = std::vector<std::byte>;
Run Code Online (Sandbox Code Playgroud)

但是,它不可能在旧式中使用它:接受它作为参数的函数失败,因为这种类型不能轻易转换为旧std::vector<unsigned char>类型,例如,zipper库的用法:

/resourcecache/pakfile.cpp: In member function 'utils::Bytes resourcecache::PakFile::readFile(const string&)':
/resourcecache/pakfile.cpp:48:52: error: no matching function for call to 'zipper::Unzipper::extractEntryToMemory(const string&, utils::Bytes&)'
     unzipper_->extractEntryToMemory(fileName, bytes);
                                                    ^
In file included from /resourcecache/pakfile.hpp:13:0,
                 from /resourcecache/pakfile.cpp:1:
/projects/linux/../../thirdparty/zipper/zipper/unzipper.h:31:10: note: candidate: bool zipper::Unzipper::extractEntryToMemory(const string&, std::vector<unsigned char>&)
     bool extractEntryToMemory(const std::string& name, std::vector<unsigned char>& vec);
          ^~~~~~~~~~~~~~~~~~~~
/projects/linux/../../thirdparty/zipper/zipper/unzipper.h:31:10: note:   no known conversion for argument 2 from 'utils::Bytes {aka std::vector<std::byte>}' to 'std::vector<unsigned char>&'
Run Code Online (Sandbox Code Playgroud)

我试图表演天真的演员,但这也没有帮助.那么,如果它被设计为有用,它在旧的上下文中是否真的有用?我看到的唯一方法是 …

c++ vector c++17

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

如何在 VSCode C++ 扩展中启用 C++17 支持

我一直在 std::string_view 上出现错误曲线,但我能够构建得很好。有没有办法告诉智能感知或 C++ linter 使用 C++17?

我得到的具体错误是:

namespace "std" has no member "string_view"
Run Code Online (Sandbox Code Playgroud)

c++ visual-studio-code c++17 vscode-settings

31
推荐指数
3
解决办法
2万
查看次数

应该通过std :: cin(gcc,clang disagree)将读取否定为无符号失败?

例如,

#include <iostream>

int main() {
  unsigned n{};
  std::cin >> n;
  std::cout << n << ' ' << (bool)std::cin << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

输入时-1,clang 6.0.0输出,0 0gcc 7.2.0输出4294967295 1.我想知道谁是对的.或者两者都是正确的标准没有指定这个?如果失败,我认为(bool)std::cin被评估为假.clang 6.0.0也输入失败-0.

c++ cin c++-standard-library language-lawyer c++17

31
推荐指数
1
解决办法
913
查看次数

为什么const auto&p {nullptr}工作而auto*p {nullptr}不能在C++ 17中工作?

这个定义有效:

const auto &b{nullptr};
Run Code Online (Sandbox Code Playgroud)

虽然失败了:

auto *b{nullptr};
Run Code Online (Sandbox Code Playgroud)

我试图在Visual C++,GCC和Clang中编译它.他们都抱怨"不能推断出类型".

在第二种情况下,不b应该推断出有某种类型的std::nullptr_t

c++ nullptr auto c++17

31
推荐指数
3
解决办法
2105
查看次数

Declaring defaulted assignment operator as constexpr: which compiler is right?

Consider

struct A1 {
    constexpr A1& operator=(const A1&) = default;
    ~A1() {}
};
struct A2 {
    constexpr A2& operator=(const A2&) = default;
    ~A2() = default;
};
struct A3 {
    ~A3() = default;
    constexpr A3& operator=(const A3&) = default;
};
Run Code Online (Sandbox Code Playgroud)

GCC and MSVC accept all three structs. Clang rejects A1 and A2 (but accepts A3), with the following error message:

<source>:2:5: error: defaulted definition of copy assignment operator is not constexpr
    constexpr A1& operator=(const A1&) = default;
    ^
<source>:6:5: error: …
Run Code Online (Sandbox Code Playgroud)

c++ language-lawyer constexpr c++17

31
推荐指数
2
解决办法
1040
查看次数

如何检查指针是否指向正确对齐的内存位置?

给定void *一些存储,如何检查它是否指向正确对齐的存储而没有任何实现定义的行为?

我们当然有std::align,但是有更有效的方法吗?

template <std::size_t alignment>
inline bool is_aligned(void * ptr) noexcept {
    std::size_t max = 1u;
    return std::align(alignment, 1u, ptr, max);
}
Run Code Online (Sandbox Code Playgroud)

PS:我需要以兼容C++标准的方式执行此操作,而不依赖于任何特定于平台的(实现定义的)黑客攻击.

PPS:我为我(理解)英语而道歉,而不是我的母语.


EDIT(2018.08.24):从标题中删除了"有效",添加了更多的措辞,强调我不希望任何实现定义或特定于平台的行为.

c++ memory-alignment c++11 c++14 c++17

30
推荐指数
1
解决办法
3397
查看次数

如何断言constexpr if else子句永远不会发生?

如果条件为真,我想在非constexpr时引发编译时错误,例如:

if constexpr(condition1){
    ...
} else if constexpr (condition2) {
   ....
} else if constexpr (condition3) {
  ....
} else {
    // I want the else clause never taken. But I heard the code below is not allowed
    static_assert(false);
}

// I'd rather not repeat the conditions again like this:
static_assert(condition1 || condition2 || condition3);
Run Code Online (Sandbox Code Playgroud)

c++ c++17

30
推荐指数
3
解决办法
1437
查看次数