小编Kno*_*abe的帖子

为什么std :: to_string没有短暂的重载?为什么没有noexcept?

有谁知道为什么在to_stringC++ 11标准的第21.5节中声明的各种函数缺少short和unsigned short的重载?如何宣布这些功能noexcept呢?这是一整套重载:

string to_string(int val);
string to_string(unsigned val);
string to_string(long val);
string to_string(unsigned long val);
string to_string(long long val);
string to_string(unsigned long long val);
string to_string(float val);
string to_string(double val);
string to_string(long double val);
Run Code Online (Sandbox Code Playgroud)

我查看了导致这些功能被采纳的提案(N1803,N1982,N2408),但没有一个有任何动机或理由.

如果我通过在一个帖子中提出两个(相当相关的,IMO)问题来违反协议,我道歉.我还是新人.

c++ c++11

10
推荐指数
1
解决办法
1010
查看次数

为什么std :: lock中没有超时支持?

如果我想在没有死锁风险的情况下获取多个锁,我可以使用该std::lock函数:

int data1, data2;
std::mutex m1, m2;
std::unique_lock<std::mutex> lock1(m1, std::defer_lock);
std::unique_lock<std::mutex> lock2(m2, std::defer_lock);

std::lock(lock1, lock2);           // guaranteed deadlock-free

// work with data1 and data2
Run Code Online (Sandbox Code Playgroud)

但是,如果我想在指定的时间内获取锁定,否则会超时怎么办?是否存在try_until类似于wait_until期货和条件变量的锁定的原因?

c++ locking c++11

10
推荐指数
2
解决办法
3221
查看次数

为什么禁止非const引用位域?

C++ 11中的第9.6/3节非常清楚:"非const引用不应绑定到位字段." 这项禁令背后的动机是什么?

我知道不可能将引用直接绑定到位域.但如果我宣布这样的话,

struct IPv4Header {
  std::uint32_t version:4,         // assumes the IPv4 Wikipedia entry is correct
                IHL:4,
                DSCP:6,
                ECN:2,
                totalLength:16;
};
Run Code Online (Sandbox Code Playgroud)

为什么我不能这样说呢?

IPv4Header h;

auto& ecn = h.ECN;
Run Code Online (Sandbox Code Playgroud)

我希望底层代码实际绑定到std::uint32_t包含我感兴趣的位的整个代码,并且我希望读取和写入操作生成代码以进行适当的屏蔽.结果可能是大而慢,但在我看来它应该工作.这与标准表示对const位域的引用有效的方式一致(同样来自9.6/3):

如果类型为const T&的引用的初始值设定项是引用位字段的左值,则引用绑定到初始化的临时值以保存位字段的值; 引用不直接绑定到位字段.

这表明写入位域是问题,但我不知道它是什么.我认为必要的屏蔽可能会在多线程代码中引入竞争,但是,根据1.7/3,非零宽度的相邻位域被认为是用于多线程的单个对象.在上面的示例中,IPv4Header对象中的所有位域都将被视为单个对象,因此根据定义,在读取其他字段时尝试修改字段的多线程代码已经很有效.

我显然遗漏了一些东西.它是什么?

c++ bit-fields c++11

10
推荐指数
2
解决办法
2094
查看次数

如何查看模板类型参数的推导类型?

是否有一种简单的方法可以强制编译器向我显示模板参数的推导类型?例如,给定

template<typename T>
void f(T&& parameter);

const volatile int * const pInt = nullptr;
f(pInt);
Run Code Online (Sandbox Code Playgroud)

我可能想看看T在调用中推断出什么类型f.(我想是的const volatile int *&,但我不确定.)或者给予

template<typename T>
void f(T parameter);

int numbers[] = { 5, 4, 3, 2, 1 };
f(numbers);
Run Code Online (Sandbox Code Playgroud)

我可能想看看我的猜测,T推断为int*在该呼叫f是正确的.

如果有第三方库解决方案(例如,来自Boost),我有兴趣了解它,但我也想知道是否有一种简单的方法可以强制进行包含推导类型的编译诊断.

c++ templates c++11

10
推荐指数
3
解决办法
2209
查看次数

有没有应该避免constexpr的情况,即使它可以使用?

如果声明了一个对象const,则保证其值仅在运行时可用,但如果声明constexpr了该值,则保证该值在编译期间和运行时都可用.因此,如果我有一个在编译期间值可用的对象,是否有任何我不应该声明它的情况constexpr

const int magicValue = 42;      // Does this ever make sense
                                // (using const instead of constexpr)?
Run Code Online (Sandbox Code Playgroud)

对于函数,如果函数可以返回编译期间计算的值,当在编译期间传递带有值的参数时,是否有意义不声明函数constexpr

struct Point { int x; int y; };

Point midPoint(Point p1, Point p2)                       // Does this ever make
{                                                        // sense (not declaring
    return { (p1.x + p2.x) / 2 , (p1.y + p2.y) / 2 };    // the function
}                                                        // constexpr)?
Run Code Online (Sandbox Code Playgroud)

我能想到的唯一情况是当你不想提交能够在使用known-at-compile-time参数调用时计算编译时常量的函数,例如,如果你想保持灵活性改变midPoint实现而不改变其界面(从而可能破坏调用者).例如,您可能希望保留将非constexpr副作用添加到midPoint例如IO 的灵活性.

c++ constexpr c++11

9
推荐指数
1
解决办法
316
查看次数

如何在编译期间计算数组大小(不接受指针)?

给定一个数组a,我想countof(a)将数组中的元素数作为编译时常量.如果我有一个指针p,我想countof(p)不编译.这似乎应该是(1)直截了当,(2)通常涵盖在SO中,但(1)我无法使它工作,并且(2)搜索SO没有发现任何东西.

这是我的尝试.

#include <cstddef>
#include <type_traits>

template<typename T, std::size_t n,
         typename = typename std::enable_if<std::is_array<T>::value>::type>
constexpr std::size_t countof(T (&)[n]) { return n; }

template<typename T, 
         typename = typename std::enable_if<std::is_pointer<T>::value>::type>
void countof(T*) = delete;

int main()
{
  int a[10];
  auto asize = countof(a);             // should compile
  static_assert(countof(a) == 10,
                "countof(a) != 10!");

  int *p;
  auto psize = countof(p);             // shouldn't compile
}
Run Code Online (Sandbox Code Playgroud)

救命?

c++ arrays templates enable-if c++11

9
推荐指数
1
解决办法
711
查看次数

是无符号short + int实现定义的类型吗?

鉴于此代码,

unsigned short us = 0; 
int i = 0;
auto sum = us + i;
Run Code Online (Sandbox Code Playgroud)

sum实现定义的类型?我对C++ 11标准的阅读是肯定的:

  • 5.7/1表示应用通常的算术转换.
  • 4.13/1子弹2和3表示int的等级大于无符号短的等级.
  • 5/9 bullet 5 subbullet 4表示如果int可以表示unsigned short中的所有值,则unsigned short将转换为int,类型sum为int.
  • 5/9 bullet 5 subbullet 5表示如果int不能表示unsigned short中的所有值,则两个操作数都将转换为unsigned int,类型sum为unsigned int.

如果上述分析是合法的,则意味着使用auto内置类型的使用算术表达式声明的变量声明可以导致实现定义的结果.我猜这会让很多程序员感到惊讶,sum上面的类型并不完全由标准决定.

我的推理合法吗?

c++ c++11

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

为什么decltype从内置类型的返回类型中删除const?

作为一般规则,decltype保留constness:

const int ci = 0;
decltype(ci)  x;         // x is const int
x = 5;                   // error--x is const

class Gadget{}:

const Gadget makeCG();         // factory

decltype(makeCG()) y1, y2;     // y1 and y2 are const Gadgets
y1 = y2;                       // error--y1 is const
Run Code Online (Sandbox Code Playgroud)

但对于const返回基本类型的返回类型,decltype似乎扔掉const了:

const int makeCI();            // factory

decltype(makeCI()) z;          // z is NOT const
z = 5;                         // okay
Run Code Online (Sandbox Code Playgroud)

为什么decltype在这种情况下丢弃常量?我的意思是两个方面的问题:

  1. 标准的哪一部分指定了这种行为?
  2. 以这种方式指定行为的动机是什么?

谢谢.

c++ decltype c++11

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

使用函数模板而不是通用lambda?

我可以写一个函数模板:

template<typename T>
void f1(T parameter) { ... }
Run Code Online (Sandbox Code Playgroud)

但是在C++ 14中,我还可以创建一个通用的lambda:

auto f2 = [](auto parameter) { ... };
Run Code Online (Sandbox Code Playgroud)

f1可以参考我T直接.在内部f2,没有T可以参考,但我可以使用decltype以下方式获得相同的效果:

auto f2 = [](auto parameter)
          {
            using T = decltype(param);
            ...
          };
Run Code Online (Sandbox Code Playgroud)

通用lambda的一个优点是我可以完美地转发它.我不能用功能模板做到这一点:

template<typename T>
void fwdToG(T&& param) { g(std::forward<T>(param)); }

fwdToG(f1);        // error!
fwdToG(f2);        // okay
Run Code Online (Sandbox Code Playgroud)

是否存在使用函数模板比​​使用通用lambda更好的情况?

c++ lambda generic-lambda c++14

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

为什么在声明移动操作时删除了复制操作?

当类显式声明复制操作(即复制构造函数或复制赋值运算符)时,不会为该类声明移动操作.但是当一个类显式声明一个移动操作时,复制操作被声明为已删除.为什么存在这种不对称?为什么不指定如果声明移动操作,则不会声明复制操作?据我所知,不存在任何行为差异,也不需要对移动和复制操作进行不对称处理.

[对于喜欢引用该标准的人,在12.8/9和12.8/20中指定缺少具有复制操作声明的类的移动操作声明,并且具有移动操作声明的类的已删除复制操作在12.8 /中指定7和12.8/18.]

c++ copy-constructor move-semantics c++11

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