在clang的C++ 11状态页面中遇到了一个名为"rvalue reference for*this"的提案.
我已经阅读了很多关于rvalue引用并理解它们的内容,但我认为我不知道这一点.我也无法使用这些条款在网上找到太多资源.
页面上的提案文件有一个链接:N2439(将移动语义扩展到*this),但我也没有从中获得太多的例子.
这个功能是什么?
指向非const数据的指针可以隐式转换为指向相同类型的const数据的指针:
int *x = NULL;
int const *y = x;
Run Code Online (Sandbox Code Playgroud)
添加额外的const限定符以匹配额外的间接寻址应该在逻辑上以相同的方式工作:
int * *x = NULL;
int *const *y = x; /* okay */
int const *const *z = y; /* warning */
Run Code Online (Sandbox Code Playgroud)
-Wall但是,使用标志对GCC或Clang进行编译会产生以下警告:
test.c:4:23: warning: initializing 'int const *const *' with an expression of type
'int *const *' discards qualifiers in nested pointer types
int const *const *z = y; /* warning */
^ ~
Run Code Online (Sandbox Code Playgroud)
为什么添加额外的const限定符"在嵌套指针类型中丢弃限定符"?
C++ 11使得基于引用限定符重载成员函数成为可能:
class Foo {
public:
void f() &; // for when *this is an lvalue
void f() &&; // for when *this is an rvalue
};
Foo obj;
obj.f(); // calls lvalue overload
std::move(obj).f(); // calls rvalue overload
Run Code Online (Sandbox Code Playgroud)
我理解这是如何工作的,但它的用例是什么?
我看到N2819建议将标准库中的大多数赋值运算符限制为左值目标(即向赋值运算符添加" &"引用限定符),但这被拒绝了.所以这是一个潜在的用例,委员会决定不再使用它.那么,再一次,什么是合理的用例?
我正在查看以下代码:
inline void* interlocked_read_acquire(void* volatile* x);
Run Code Online (Sandbox Code Playgroud)
并且我想知道为什么不仅仅volatile void*作为一个论点.一般来说,什么是语义或定义volatile*?我也假设您可以使用volatile*除void之外的任何其他类型的限定符.那是对的吗?
有没有办法实现自定义类型限定符(类似于const)?我想只允许函数调用具有相同资格的函数中具有相同资格的函数.
假设我会:
void allowedFunction();
void disallowedFunction();
//Only allowed to call allowed functions.
void foo()
{
allowedFunction();
disallowedFunction(); //Cause compile time error
}
//Is allowed to call any function it wants.
void bar()
{
allowedFunction();
disallowedFunction(); //No error
}
Run Code Online (Sandbox Code Playgroud)
我想这样做的原因是因为我想确保在特定线程上调用的函数只调用实时安全函数.由于许多应用程序需要硬实时安全线程,因此在编译时使用某种方法检测锁定将保证我们不会发生许多难以检测的运行时错误.
如果我想提取const引用的类型(比如const double&的double),我是否必须使用:
typename std::remove_cv<typename std::remove_reference<Type>::type>::type
Run Code Online (Sandbox Code Playgroud)
要么
typename std::remove_reference<typename std::remove_cv<Type>::type>::type
Run Code Online (Sandbox Code Playgroud)
?
C++ 03可以让你有资格函数的参数为const,volatile和/或左值引用(&).
C++ 11增加了一个:rvalue references(&&).
此外,C++允许您根据参数的限定符重载函数,以便在调用函数时选择最合适的重载.
成员函数在概念上可以被认为是一个函数,它接受一个额外的参数,其类型是对它所属的类的实例的引用.可以基于此"额外参数"的限定符来重载成员函数,其方式与任何其他参数非常相似.这通过将限定符放在函数签名的末尾来表示:
struct Foo
{
int& data(); // return a non-const reference if `this` is non-const
const int& data() const; // return a const reference if `this` is const
};
Run Code Online (Sandbox Code Playgroud)
在C++ 03,const和volatile预选赛是可能的,C++ 11还允许&和&&(&理论上可以被允许在C++ 03,但它不是).
可以使用限定符的任何组合,除了&并且&&是互斥的,这使得C++ 03中的2 ^ 2 = 4种可能性和C++ 11中的2 ^ 4-4 = 12.
当你想使用成员函数指针时,这可能会非常痛苦,因为它们在这些限定符中甚至不是多态的:this作为参数传递的成员函数指针的" 类型" 的限定符必须与那些完全匹配关于它被传递的参数的类型.C++也没有提供用于抽象限定符的明确工具.在C++ 03中,这基本上没问题,因为你必须编写一个const版本和一个非 …
我有两个结构:
// ----- non-const -----
struct arg_adapter
{
EArgType type; // fmtA, fmtB, ...
union
{
TypeA * valueA;
TypeB * valueB;
// ... more types
}
arg_adapter(TypeA & value) : type(fmtA), valueA(&value) {}
arg_adapter(TypeB & value) : type(fmtB), valueB(&value) {}
// ...
}
// ----- const version -----
struct const_arg_adapter
{
EArgType type; // fmtA, fmtB, ...
union
{
TypeA const * valueA;
TypeB const * valueB;
// ... more types
}
arg_adapter(TypeA const & value) : type(fmtA), valueA(&value) …Run Code Online (Sandbox Code Playgroud) 我知道这个函数很简单,它将被内联:
int foo(int a, int b){
return a + b;
}
Run Code Online (Sandbox Code Playgroud)
但我的问题是,编译器无法自动检测到这与以下内容相同:
int foo(const int a, const int b){
return a + b;
}
Run Code Online (Sandbox Code Playgroud)
既然可以检测到这一点,为什么我需要在const任何地方输入?我知道inline由于编译器的进步,关键字已经过时了.是不是该const做同样的时间?
在这个例子中,是否需要global_value声明正确性volatile?
int global_value = 0;
void foo () {
++ global_value;
}
void bar () {
some_function (++global_value);
foo ();
some_function (++global_value);
}
Run Code Online (Sandbox Code Playgroud)
我的理解是volatile" 指向 "用于指向映射内存和变量的指针,这些指针可以通过信号修改(并且强调不是为了线程安全)但是很容易想象bar可能编译成这样的东西:
push EAX
mov EAX, global_value
inc EAX
push EAX
call some_function
call foo
inc EAX
push EAX
call some_function
mov global_value, EAX
pop EAX
Run Code Online (Sandbox Code Playgroud)
这显然是不正确的,但即使没有volatile我认为根据C抽象机器它是有效的.我错了还是有效?
如果是这样的话,在我看来volatile经常被忽视.这不是什么新鲜事!
void baz (int* i) {
some_function (++*i);
foo (); …Run Code Online (Sandbox Code Playgroud) qualifiers ×10
c++ ×9
c++11 ×4
c ×2
const ×2
overloading ×2
volatile ×2
c++-faq ×1
compile-time ×1
pointers ×1
reference ×1
templates ×1
type-traits ×1