小编Lin*_*gxi的帖子

初始化枚举的值的行为

首先,我想说,根据cppreference.com,对枚举值进行初始化是不可能的.

根据http://en.cppreference.com/w/cpp/language/value_initialization,初始化枚举值实际上执行零初始化.然后,根据http://en.cppreference.com/w/cpp/language/zero_initialization,零初始化枚举的效果是:

如果T是标量类型,则对象的初始值是隐式转换为的整数常量零T.

但是,整数常数零不能隐式转换为枚举.最终,枚举不能进行价值初始化.这听起来很奇怪,并且枚举值的初始值确实适用于VC,GCC和clang.那么,标准对此有何看法?

其次,根据http://en.cppreference.com/w/cpp/language/static_cast:

整数,浮点或枚举类型可以转换为任何完整的枚举类型(结果是未指定的(直到C++ 17)未定义的行为(自C++ 17)如果表达式的值转换为枚举的基础类型,不是目标枚举值之一)

那么,这是否意味着如果目标枚举没有枚举器等于,则初始化枚举值(如果它可以工作)可能实际上导致未定义的行为0

c++ enums initialization language-lawyer value-initialization

33
推荐指数
1
解决办法
7344
查看次数

应该通过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
查看次数

std :: make_shared()在C++中的变化17

cppref中,以下内容一直持续到C++ 17:

f(std::shared_ptr<int>(new int(42)), g())如果g在之后调用new int(42)并抛出异常,则可能导致内存泄漏的代码,同时f(std::make_shared<int>(42), g())是安全的,因为两个函数调用永远不会交错.

我想知道在C++ 17中引入了哪些更改使其不再适用.

c++ language-lawyer make-shared exception-safety c++17

27
推荐指数
2
解决办法
2472
查看次数

std :: abs的模板版本

这里列出了std::absC++ 中的当前重载.我想知道为什么不定义以下模板并放弃所有丑陋的C风格重载?

template <typename T> inline
T abs(const T& v) { return v < 0 ? -v : v; }
Run Code Online (Sandbox Code Playgroud)

c++ templates cmath

24
推荐指数
2
解决办法
3779
查看次数

在现代C++中优雅地定义多维数组

使用T[][][]语法定义多维数组很容易.但是,这会创建一个原始数组类型,它不适合现代C++.这就是我们std::array从C++ 11开始的原因.但是使用多维数组来定义多维数组的语法std::array非常混乱.例如,要定义三维int数组,您必须编写std::array<std::array<std::array<int, 5>, 5>, 5>.语法根本不可扩展.我要求解决这个问题.也许,使用C++提供的现有实用程序无法修复此问题.在这种情况下,我很高兴开发了一种自定义工具来简化语法.

自己找到了解决方案:

template <typename T, std::size_t n, std::size_t... ns>
struct multi_array {
  using type = std::array<typename multi_array<T, ns...>::type, n>;
};

template <typename T, std::size_t n>
struct multi_array<T, n> {
  using type = std::array<T, n>;
};

template <typename T, std::size_t... ns>
using multi_array_t = typename multi_array<T, ns...>::type;
Run Code Online (Sandbox Code Playgroud)

想知道是否可以进一步简化实施.

c++ arrays multidimensional-array template-meta-programming c++14

24
推荐指数
1
解决办法
4228
查看次数

std :: make_shared是否执行值初始化(GCC和clang不同意)?

我所说的意思可以通过以下示例来解释:

auto p = std::make_shared<int>();

int可变缺省初始化(因此具有垃圾值)或值初始化(从而具有零的值)?我已经在GCC 5.2和clang 3.6上进行了测试,前者进行了值初始化,后者进行了默认初始化.我想知道标准对此有何看法?在我看来,现代C++肯定应该在这种情况下执行值初始化.

c++ initialization language-lawyer c++11

22
推荐指数
2
解决办法
871
查看次数

std :: reference_wrapper问题

使用以下代码可以清楚地解决该问题:

#include <functional>
#include <iostream>
#include <vector>

int main() {
  //std::vector<int> a, b;
  int a = 0, b = 0;
  auto refa = std::ref(a);
  auto refb = std::ref(b);
  std::cout << (refa < refb) << '\n';
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

如果我使用注释std::vector<int> a, b;而不是int a = 0, b = 0;,则代码不会在GCC 5.1,clang 3.6或MSVC'13中的任何一个上编译.在我看来,std::reference_wrapper<std::vector<int>>可以隐式转换std::vector<int>&为LessThanComparable,因此它应该是LessThanComparable本身.有人可以向我解释一下吗?

c++ language-lawyer implicit-conversion c++11 reference-wrapper

17
推荐指数
1
解决办法
1055
查看次数

最简洁的方法来禁用复制和移动语义

以下肯定有效,但非常繁琐:

T(const T&) = delete;
T(T&&) = delete;
T& operator=(const T&) = delete;
T& operator=(T&&) = delete;
Run Code Online (Sandbox Code Playgroud)

我正试图发现最简洁的方式.以下工作会吗?

T& operator=(T) = delete;
Run Code Online (Sandbox Code Playgroud)

更新

请注意,我选择T& operator=(T)而不是T& operator=(const T&)T& operator=(T&&),因为它可以同时满足两个目的.

c++ copy move-semantics c++11

17
推荐指数
3
解决办法
2944
查看次数

noexcept说明符神秘地打破了编译(clang,gcc不同意)

有问题的代码是

#include <functional>
#include <utility>

template <typename F>
void for_each(F&&) noexcept {}

template <typename F, typename T, typename... Us>
void for_each(F&& f, T&& v, Us&&... us) {
  std::invoke(std::forward<F>(f), std::forward<T>(v));
  for_each(std::forward<F>(f), std::forward<Us>(us)...);
}

void func(void*) noexcept {}

int main() {
  for_each(func, nullptr);
}
Run Code Online (Sandbox Code Playgroud)

它在gcc 8编译,但在clang 6上失败,出现以下错误:

/opt/wandbox/clang-6.0.0/include/c++/v1/type_traits:4198:19: error: invalid application of 'sizeof' to a function type
    static_assert(sizeof(_Tp) > 0, "Type must be complete.");
                  ^~~~~~~~~~~
/opt/wandbox/clang-6.0.0/include/c++/v1/type_traits:4203:15: note: in instantiation of template class 'std::__1::__check_complete<void (void *) noexcept>' …
Run Code Online (Sandbox Code Playgroud)

c++ gcc clang noexcept c++11

17
推荐指数
1
解决办法
704
查看次数

C++中的默认参数vs重载

例如,而不是

void shared_ptr::reset() noexcept;
template <typename Y>
void shared_ptr::reset(Y* ptr);
Run Code Online (Sandbox Code Playgroud)

人们可能会想到

template <typename Y = T>
void shared_ptr::reset(Y* ptr = nullptr);
Run Code Online (Sandbox Code Playgroud)

我认为这里的性能差异可以忽略不计,第二个版本更简洁.有没有具体的原因C++标准是第一种方式?

同样的问题已经被问了科特林语言,默认参数为首选那里.

更新:

std::unique_ptr::reset()遵循默认参数设计(参见此处).所以我认为std::shared_ptr::reset()使用重载的原因是因为它们有不同的异常规范.

c++ api-design overloading language-lawyer default-arguments

16
推荐指数
3
解决办法
1459
查看次数