小编Kno*_*abe的帖子

为什么运算符[]不为lvalues和rvalues重载?

标准C++容器只提供一个operator[]容器版本,如vector<T>deque<T>.它返回一个T&(除了for vector<bool>,我将忽略),这是一个左值.这意味着在这样的代码中,

vector<BigObject> makeVector();       // factory function

auto copyOfObject = makeVector()[0];  // copy BigObject
Run Code Online (Sandbox Code Playgroud)

copyOfObject将被复制.鉴于makeVector()返回rvalue vector,期望copyOfObject移动构造似乎是合理的.

如果operator[]为rvalue和lvalue对象重载了这样的容器,那么operator[]对于右值容器,可以返回一个右值引用,即一个rvalue:

template<typename T>
container {
public:
    T& operator[](int index) &;       // for lvalue objects
    T&& operator[](int index) &&;     // for rvalue objects
...
};
Run Code Online (Sandbox Code Playgroud)

在这种情况下,copyOfObject将移动构建.

总的来说,这种超载是一个坏主意吗?有没有理由为C++ 14中的标准容器做到这一点?

c++ operator-overloading c++11

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

使用未命名的命名空间会减少链接时间吗?

假设我有一个包含许多目标文件的大型系统,这样链接时间就成了问题.还假设我知道我的系统中的许多类和函数都没有在翻译单元之外使用.

  1. 假设如果我减少带有外部链接的符号数量,我的链接时间会减少吗?
  2. 如果是这样,将仅在单个TU中使用的实体(例如,类和函数)放入未命名的命名空间对我有用吗?从技术上讲,具有外部链接的实体将在未命名的命名空间中保留其外部链接,但是,正如C++ 11标准所指出的那样,

虽然未命名的命名空间中的实体可能具有外部链接,但它们实际上由其翻译单元唯一的名称限定,因此永远不会从任何其他翻译单元中看到.

链接器算法是否基于以下知识执行优化:未命名的命名空间中具有外部链接的实体在其命名空间之外是不可见的?

c++

16
推荐指数
1
解决办法
493
查看次数

为什么nullptr不能转换为int?

总结:nullptr转换为bool,bool转换为int,为什么不nullptr转换为int

这段代码没问题:

void f(bool);
f(nullptr);      // fine, nullptr converts to bool
Run Code Online (Sandbox Code Playgroud)

这没关系:

bool b;
int i(b);        // fine, bool converts to int
Run Code Online (Sandbox Code Playgroud)

那么为什么这不行呢?

void f(int);
f(nullptr);      // why not convert nullptr to bool, then bool to int?
Run Code Online (Sandbox Code Playgroud)

c++ nullptr implicit-conversion c++11

16
推荐指数
2
解决办法
6432
查看次数

result_of <F(Args ...>和decltype <f(args ...)>之间有什么区别?

我看到它std::async的具体说明如下:

template <class F, class... Args>                   // copied out of the standard
future<typename result_of<F(Args...)>::type>
async(F&& f, Args&&... args);
Run Code Online (Sandbox Code Playgroud)

我曾预料到它会被声明为:

template <class F, class... Args>
auto async(F&& f, Args&&... args) ->
  future<decltype(forward<F>(f)(forward<Args>(args)...)>;
Run Code Online (Sandbox Code Playgroud)

那是相同的,还是有某种方式使用它比使用result_of更好decltype?(我理解它result_of适用于类型,同时decltype适用于表达式.)

c++ c++11

14
推荐指数
3
解决办法
1973
查看次数

为什么C++ 11 CAS操作需要两个指针参数?

许多C++ 11 CAS操作(例如,的atomic_compare_exchange_weak,atomic_compare_exchange_strong)取两个指针和值,即,是这样的:

bool atomic_compare_exchange(T* pointer, T* expected,       // pseudodeclaration!
                             T desired);
Run Code Online (Sandbox Code Playgroud)

相比之下,来自Microsoft,gcc和Intel的CAS操作都采用一个指针和两个值:

long InterlockedCompareExchange(long* pointer, long desired,       // Microsoft
                                long expected);

int __sync_bool_compare_and_swap (T* pointer, T expected,          // gcc and
                                  T desired);                      // Intel
Run Code Online (Sandbox Code Playgroud)

为什么C++ 11 CAS函数需要两个指针和一个值,而不是看起来更传统的一个指针和两个值?

c++ compare-and-swap c++11

14
推荐指数
1
解决办法
4114
查看次数

为什么std :: is_base_of <T,T>当T是类类型时为true,但是当T是内置类型时为false?

对于类类型T,Per [meta.rel](在C++ 14中为20.10.6)std::is_base_of<T,T>是正确的,但对于内置类型T,std::is_base_of<T,T>则为false.通俗地说,类类型是它们自己的基础,但内置类型不是.这种治疗差异的动机/效用是什么?

c++ type-traits c++11 c++14

14
推荐指数
2
解决办法
999
查看次数

T是C++中的模板实例吗?

假设我在模板中,我想知道类型参数T是否是特定模板的实例化,例如std::shared_ptr:

template<typename T>
void f(T&& param)
{
    if (instantiation_of(T, std::shared_ptr)) ...   // if T is an instantiation of 
                                                    // std::shared_ptr...
  ...
}
Run Code Online (Sandbox Code Playgroud)

更有可能我想在std :: enable_if测试中进行这种测试:

template<typename T>
std::enable_if<instantiation_of<T, std::shared_ptr>::type
f(T&& param) 
{
    ...
}

// other overloads of f for when T is not an instantiation of std::shared_ptr
Run Code Online (Sandbox Code Playgroud)

有没有办法做到这一点?请注意,该解决方案需要使用所有可能的类型和模板,包括标准库和我无法修改的其他库中的那些.我对std::shared_ptr上面的使用仅仅是我想要做的一个例子.

如果这是可能的,我将如何自己编写测试,即实现instantiation_of

c++ templates

13
推荐指数
2
解决办法
676
查看次数

"int size = 10;" 产生一个恒定的表达?

以下代码在gcc 4.8和Clang 3.2下编译:

int main()
{
  int size = 10;
  int arr[size];
}
Run Code Online (Sandbox Code Playgroud)

C++标准的8.3.4/1表示数组的大小必须是一个整数常量表达式,这size似乎不是.这是两个编译器中的错误,还是我错过了什么?

最新的VC++ CTP用这个有趣的消息拒绝代码:

error C2466: cannot allocate an array of constant size 0
Run Code Online (Sandbox Code Playgroud)

有趣的是,它似乎认为size是零.但至少它拒绝了代码.gcc和Clang应该不一样吗?

c++ arrays compile-time-constant variable-length-array c++11

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

是否可以重新订购对挥发物的访问?

考虑以下对volatile内存的写入顺序,我从David Chisnall在InformIT的文章 "理解C11和C++ 11 Atomics"中获取:

volatile int a = 1;
volatile int b = 2;
             a = 3;
Run Code Online (Sandbox Code Playgroud)

我对C++ 98的理解是,根据C++ 98 1.9,这些操作无法重新排序:

符合实现需要模拟(仅)抽象机器的可观察行为,如下所述...抽象机器的可观察行为是它对易失性数据的读写顺序和对库I/O函数的调用

Chisnall说,对订单保存的约束仅适用于单个变量,写出符合要求的实现可以生成执行此操作的代码:

a = 1;
a = 3;
b = 2;
Run Code Online (Sandbox Code Playgroud)

或这个:

b = 2;
a = 1;
a = 3;
Run Code Online (Sandbox Code Playgroud)

C++ 11重复了C++ 98的措辞

符合实现需要模拟(仅)抽象机器的可观察行为,如下所述.

但这说关于volatiles(1.9/8):

严格根据抽象机器的规则来评估对volatile对象的访问.

1.9/12表示访问volatileglvalue(包括变量a,bc以上)是副作用,1.9/14表示一个完整表达式(例如,一个语句)中的副作用必须先于后面的副作用在同一个线程中完整表达.这使我得出结论,Chisnall显示的两个重新排序是无效的,因为它们不符合抽象机器所规定的排序.

我忽略了什么,还是Chisnall错了?

(请注意,这不是一个线程问题.问题是是否允许编译器重新排序对volatile单个线程中不同变量的访问.)

c++ volatile c++11

11
推荐指数
2
解决办法
1160
查看次数

为什么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
查看次数