标签: c++17

为什么new []表达式曾经调用析构函数?

根据C ++ 17标准(此处为草案),[expr.new]:

如果new表达式创建一个对象或一个类类型的对象数组,则将对分配函数,释放函数和构造函数进行访问和歧义控制。如果new表达式创建了一个类类型的对象数组,则可能会调用析构函数。

为什么要new[]调用析构函数?毕竟是新的。它不是删除。

c++ new-operator c++17

39
推荐指数
3
解决办法
1412
查看次数

为什么分解声明不能成为constexpr?

考虑以下片段来测试即将发布的C++ 17特性分解声明(以前称为结构化绑定)

#include <cassert>
#include <utility>

constexpr auto divmod(int n, int d)
{
    return std::make_pair(n / d, n % d); // in g++7, also just std::pair{n/d, n%d}
}

int main()
{
    constexpr auto [q, r] = divmod(10, 3);
    static_assert(q == 3 && r ==1);
}
Run Code Online (Sandbox Code Playgroud)

这在g ++ 7-SVN和clang-4.0-SVN上都失败了,并带有以下消息:

分解声明不能声明'constexpr'

删除constexpr定义并更改为assert()两个编译器上的常规工作.

关于此功能的WG21论文constexpr均未提及关键字,无论是正面还是负面.

问题:为什么不允许分解声明constexpr?(除了"因为标准这么说").

c++ constexpr c++17 structured-bindings

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

为什么这个"未定义的外部变量"不会导致C++ 17中的链接器错误?

我已经在C++ 17编译器(Coliru)中编译并运行了以下程序.在程序中,我声明了一个extern变量,但没有定义它.但是,编译器不会给出链接器错误.

#include <iostream>

extern int i; // Only declaration

int func() 
{
    if constexpr (true)
        return 0;
    else if (i)
        return i;
    else
        return -1;
}

int main() 
{
    int ret = func();
    std::cout<<"Ret : "<<ret<<std::endl;
}
Run Code Online (Sandbox Code Playgroud)

为什么编译器没有给出链接器错误?

c++ linker-errors extern c++17 if-constexpr

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

如何在CMake中启用C++ 17

我正在使用VS 15.3,它支持集成的CMake 3.8.如何在不为每个特定编译器编写标志的情况下定位C++ 17?我当前的全局设置不起作用:

# https://cmake.org/cmake/help/latest/prop_tgt/CXX_STANDARD.html
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)

# expected behaviour
#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /std:c++lastest")
Run Code Online (Sandbox Code Playgroud)

我希望CMake在生成VS解决方案文件时添加"/ std:c ++ lastest"或等价物,但是没有找到c ++ 17标志,导致编译器错误:

C1189 #error: class template optional is only available with C++17.
Run Code Online (Sandbox Code Playgroud)

c++ cmake visual-studio c++17

38
推荐指数
6
解决办法
4万
查看次数

为什么在C++ 17中添加了std :: reduce?

我正在寻找对"返回值"描述的含义的详尽解释std::reduce,根据cppreference.com,它是:

在此输入图像描述

也许在我能够正确地理解"返回值"部分背后的想法之后,我可以更好地确定我应该选择std::reduce的位置std::accumulate.

c++ std c++17

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

返回类型时c_str()与data()

在C++ 11之后,我想到了c_str()并且data() 等效.

C++ 17为后者引入了一个重载,返回一个非常量指针(引用,我不确定它是否完全在C++ 17中更新):

const CharT* data() const;    (1)   
CharT* data();                (2)   (since C++17)
Run Code Online (Sandbox Code Playgroud)

c_str() 只会返回一个常量指针:

const CharT* c_str() const;
Run Code Online (Sandbox Code Playgroud)

为什么在C++ 17中区分这两种方法,特别是当C++ 11是使它们成为同构的时候?换句话说,为什么只有一种方法过载,而另一种方法没有?

c++ string c-str c++17

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

与[[maybe_unused]]结构化绑定

具有模式匹配的函数式语言(有时?)有可能忽略一些绑定值,但是使用C++ 17结构化绑定似乎没有办法(std :: ignore with structured bindings?).建议是使用虚拟名称,但随后我们会收到有关未使用变量的警告.

有了clang和gcc的最新元首,这就做了预期的事情,这很好用,

[[maybe_unused]] auto x =4 ; // fine, no warning
[[maybe_unused]] auto [a,dummyb,dummyc] = std::tuple<int,int,float>(1,1,1.0f); 
Run Code Online (Sandbox Code Playgroud)

但我也希望这会奏效:

auto [g,[[maybe_unused]]dummyh,[[maybe_unused]]dymmyi] =
      std::tuple<int,int,float>(1,1,1.0f);
Run Code Online (Sandbox Code Playgroud)

是否有一个特定的原因属性不能在这里使用?(在标准和技术上).gcc或clang都不接受这个.


编辑,收集支持状态:(感谢godbolt /编译器浏览器).它按预期工作(也可能更早):

  • gcc 8.0 trunk(g ++ 8.0.0 20171015实验)
  • 铿锵4.0.0
  • icc 18(未经测试,根据规格)

MSVC 17.3.5(和Visual Studio GUI)允许该属性,但它不适用于结构化绑定.错误报告

c++ c++17 structured-bindings

37
推荐指数
2
解决办法
4290
查看次数

找不到macOS Clang C++ 17文件系统头文件

我需要使用(实验性)C++17文件系统库编写程序,但clang在我的Mac(macOS 10.12.03)上似乎没有包含文件系统头.

由于我需要使用C++17,我不能使用像Boost库这样的替代品.

当我尝试编译一个只包含文件系统和iostream(并写入cout)的示例程序时

#include <filesystem>
#include <iostream>
using namespace std;

int main(){
    cout << "test" << endl;
}
Run Code Online (Sandbox Code Playgroud)

我收到以下错误消息:

>clang test.cpp -std=c++1z

test.cpp:2:10: fatal error: 'filesystem' file not found
#include <filesystem>
         ^
1 error generated.
Run Code Online (Sandbox Code Playgroud)

当我尝试使用GCC 6.3(通过自制软件安装)时,我得到:

>gcc-6 test.cpp  -std=c++17 
test.cpp:2:22: fatal error: filesystem: No such file or directory
 #include <filesystem>
                      ^
compilation terminated.
Run Code Online (Sandbox Code Playgroud)

我也试过使用实验/文件系统而不是编译使用gcc但似乎尝试编译为iOS导致另一个错误,这似乎与iostream

Undefined symbols for architecture x86_64:
  "std::ios_base::Init::Init()", referenced …
Run Code Online (Sandbox Code Playgroud)

c++ macos gcc clang c++17

37
推荐指数
4
解决办法
3万
查看次数

我需要把constexpr放在其他地方 - 如果?

受此答案的启发,我尝试复制并粘贴(并添加测试main())此代码:

template<typename T>
std::tuple<int, double> foo(T a) {
    if constexpr (std::is_same_v<int, T>)
        return {a, 0.0};
    else if (std::is_same_v<double, T>)
        return {0, a};
    else
        return {0, 0.0};
}

int main() {
    auto [x, y] = foo("");
    std::cout << x << " " << y;
}
Run Code Online (Sandbox Code Playgroud)

这非常简单 - 如果T推断为int,我们想要返回一个元组[a, 0.0].如果T推断为double,我们想要返回一个元组 [0, a].否则,我们想要回来[0, 0.0].

正如你所看到的,在main()函数中,我fooconst char*参数调用,这应该导致x和 …

c++ if-statement c++17 if-constexpr

37
推荐指数
1
解决办法
2525
查看次数

为什么这个派生类可以在 C++17 上用 `{}` 而不是用 `()` 构造?

在这个例子中,C++17 可以使用 Base 类的构造函数构造派生类{},但不能使用()
这也适用于 GCC 和 Clang 的 C++20,但不适用于 MSVC。
为什么我可以这样构造派生类?安全吗?

我查看了 C++17 中的添加和更改,但找不到允许这样做的更改。
我很可能是瞎子。

#include <iostream>

class Base {
public:
    Base(const int value) {
        std::cout << "Constructed with value: " << value << '\n';
    }
};

class Derived : public Base {
};

int main(){
    // does compile on C++17 with MSVC
    // does not compile pre or post C++17 with MSVC
    // does compile on and post C++17 on GCC and Clang
    // …
Run Code Online (Sandbox Code Playgroud)

c++ c++17

37
推荐指数
1
解决办法
1157
查看次数