标准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中的标准容器做到这一点?
假设我有一个包含许多目标文件的大型系统,这样链接时间就成了问题.还假设我知道我的系统中的许多类和函数都没有在翻译单元之外使用.
虽然未命名的命名空间中的实体可能具有外部链接,但它们实际上由其翻译单元唯一的名称限定,因此永远不会从任何其他翻译单元中看到.
链接器算法是否基于以下知识执行优化:未命名的命名空间中具有外部链接的实体在其命名空间之外是不可见的?
总结: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) 我看到它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++ 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函数需要两个指针和一个值,而不是看起来更传统的一个指针和两个值?
对于类类型T,Per [meta.rel](在C++ 14中为20.10.6)std::is_base_of<T,T>是正确的,但对于内置类型T,std::is_base_of<T,T>则为false.通俗地说,类类型是它们自己的基础,但内置类型不是.这种治疗差异的动机/效用是什么?
假设我在模板中,我想知道类型参数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?
以下代码在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
考虑以下对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,b及c以上)是副作用,1.9/14表示一个完整表达式(例如,一个语句)中的副作用必须先于后面的副作用在同一个线程中完整表达.这使我得出结论,Chisnall显示的两个重新排序是无效的,因为它们不符合抽象机器所规定的排序.
我忽略了什么,还是Chisnall错了?
(请注意,这不是一个线程问题.问题是是否允许编译器重新排序对volatile单个线程中不同变量的访问.)
有谁知道为什么在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)问题来违反协议,我道歉.我还是新人.