我发现自己并没有完全理解它的逻辑std::move().
起初,我用谷歌搜索它,但似乎只有关于如何使用的文件std::move(),而不是它的结构如何工作.
我的意思是,我知道模板成员函数是什么,但是当我std::move()在VS2010中查看定义时,它仍然令人困惑.
std :: move()的定义如下.
template<class _Ty> inline
typename tr1::_Remove_reference<_Ty>::_Type&&
move(_Ty&& _Arg)
{ // forward _Arg as movable
return ((typename tr1::_Remove_reference<_Ty>::_Type&&)_Arg);
}
Run Code Online (Sandbox Code Playgroud)
首先对我来说奇怪的是参数,(_Ty && _Arg),因为当我调用函数时,如下所示,
// main()
Object obj1;
Object obj2 = std::move(obj1);
Run Code Online (Sandbox Code Playgroud)
它基本上等于
// std::move()
_Ty&& _Arg = Obj1;
Run Code Online (Sandbox Code Playgroud)
但正如您已经知道的那样,您不能直接将LValue链接到RValue引用,这让我觉得它应该是这样的.
_Ty&& _Arg = (Object&&)obj1;
Run Code Online (Sandbox Code Playgroud)
但是,这是荒谬的,因为std :: move()必须适用于所有值.
所以我想要完全理解它是如何工作的,我也应该看看这些结构.
template<class _Ty>
struct _Remove_reference
{ // remove reference
typedef _Ty _Type;
};
template<class _Ty>
struct _Remove_reference<_Ty&>
{ // remove reference
typedef _Ty _Type;
}; …Run Code Online (Sandbox Code Playgroud) 可能重复:
从模板函数调用的模板类的C++模板成员函数
template<class T1>
class A
{
public:
template<class T0>
void foo() const {}
};
template<class T0,class T1>
void bar( const A<T1>& b )
{
b.foo<T0>(); // This throws " expected primary-expression before ‘>’ token"
}
Run Code Online (Sandbox Code Playgroud)
我可以改成它
b->A<T1>::template foo<T0>();
Run Code Online (Sandbox Code Playgroud)
编译好.不过我也可以改成它
b.A<T1>::template foo<T0>();
Run Code Online (Sandbox Code Playgroud)
编译也很好.是吗?
如何在原始代码的意义上正确调用模板成员函数?
我花了很长时间才发现我的代码中有一个错误被触发/OPT:ICF:
因为/ OPT:ICF可以将相同的地址分配给不同的函数或只读数据成员(使用/ Gy编译的const变量),它可以破坏依赖于函数或只读数据成员的唯一地址的程序.
(我一直在存储和比较函数指针的相等性,当链接器丢弃相同的函数时会断开这些指针.)
现在我需要找到我可能做过这样事情的每一个地方.
测试用例当然是微不足道的:
//MSVC: /Gy /link /OPT:ICF
int test1(void) { return 0; }
int test2(void) { return 0; }
int main(void) { return test1 == test2; }
Run Code Online (Sandbox Code Playgroud)
我试过-Wall,-Wextra,-Weverything,-pedantic,等,但他们没有产生警告.
是否有任何编译器选项或工具(无论是Visual C++,GCC,Clang还是其他部分)可以分析我的代码并告诉我在哪里比较函数指针,就像在上面的代码中一样?
根据此,一个函数声明constexpr必须满足一些要求,其中之一是如下:
存在至少一个参数值,使得函数的调用可以是核心常量表达式的计算子表达式...
好吧,constexpr函数没有参数:
constexpr int Bar( /* empty */ ) { return 0xFF; }
constexpr int value = Bar(); // Valid expression
Run Code Online (Sandbox Code Playgroud)
constexpr 作为子例程调用的函数也不能将整个表达式确定为核心常量表达式.
那么一个参数值必须存在意味着什么呢?
[未来读者更新]
显然,关于要求的描述constexpr function已经修复,因为这个问题来自:
存在至少一个参数值,使得函数的调用可以是核心常量表达式的计算子表达式...
至:
存在至少一组参数值,以便函数的调用可以是核心常量表达式的计算子表达式...
假设我们有一个名为AAA支持复制/移动的类:
class AAA
{
public:
AAA() = default;
~AAA() = default;
AAA(const AAA& rhs)
{
std::cout << "Copy constructor" << std::endl;
}
AAA(AAA&& rhs)
{
std::cout << "Move constructor" << std::endl;
}
};
Run Code Online (Sandbox Code Playgroud)
在以下代码中,get_val返回second:
AAA get_val()
{
auto [ first, second ] = std::make_tuple(AAA{}, AAA{});
std::cout << "Returning - " << std::endl;
return second;
}
auto obj = get_val();
std::cout << "Returned - " << std::endl;
Run Code Online (Sandbox Code Playgroud)
现在second被复制,打印以下输出:
...
Returning - …Run Code Online (Sandbox Code Playgroud) 考虑以下:
template<typename T>
struct C {};
template<typename T, typename U>
void operator +(C<T>&, U);
struct D: C<D> {};
struct E {};
template<typename T>
void operator +(C<T>&, E);
void F() { D d; E e; d + e; }
Run Code Online (Sandbox Code Playgroud)
此代码在GCC-7和Clang-5上编译良好.选定的重载operator +是struct E.
现在,如果发生以下变化:
/* Put `operator +` inside the class. */
template<typename T>
struct C {
template<typename U>
void operator +(U);
};
Run Code Online (Sandbox Code Playgroud)
即,如果operator +被定义内部类模板,代替外,再产生锵歧义之间的两个operator +S出现在代码中.海湾合作委员会仍然编制好.
为什么会这样?这是GCC还是Clang的错误?
xvalue的定义如下:
- xvalue("eXpiring"值)也指对象,通常接近其生命周期的末尾(例如,可以移动其资源).xvalue是涉及rvalue引用的某些表达式的结果(8.3.2).[示例:调用返回类型为右值引用的函数的结果是xvalue. - 末端的例子]
我们是否会陷入我们实际需要使用其返回类型为右值引用的函数的位置,该函数是xvalue?
const int && Foo()
{
// ...
}
Run Code Online (Sandbox Code Playgroud)
移动语义将右值引用作为参数,而不是返回值.所以我认为不是这样的.
Microsoft.Bcl.Async使开发人员能够使用async/await没有.NET Framework 4.5的关键字,以便他们使用它们.
这很棒,这得益于Microsoft CLR和语言团队中人员的辛勤工作.
现在我很好奇这是如何工作的.
async/await 要求编译器做一些繁重的工作来将代码变成可以等待操作的东西.
编译器最初在.NET Framework 4.0下抛出编译错误,即使它清楚地知道什么async/await意思(Visual Studio 2012/2013.)
那么这个库如何告诉编译器不要抛出与异步操作相关的特定编译错误,并且像在.NET Framework 4.5下一样解除一些代码?
我试图在C#代码中实现vuforia api.
我从服务器收到错误.
C#代码:
ASCIIEncoding Encoding = new ASCIIEncoding();
MD5 md5 = MD5.Create();
string requestPath = "/targets";
string serviceURI = "https://vws.vuforia.com"+ requestPath;
string httpVerb = "GET";
var contentMD5bytes = md5.ComputeHash(Encoding.GetBytes(""));
string contentMD5 = BitConverter.ToString(contentMD5bytes).Replace("-", "");
string contentType = "";
System.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("en-US");
string date = string.Format("{0:r}", DateTime.Now.ToUniversalTime());
string StringToSign = String.Format("{0}\n{1}\n{2}\n{3}\n{4}", httpVerb, contentMD5, contentType, date, requestPath); // HTTP-Verb, Content-MD5, Content-Type, Date, Request-Path;
HMACSHA1 sha1 = new HMACSHA1(System.Text.Encoding.ASCII.GetBytes(secretKey));
byte[] sha1Bytes = Encoding.GetBytes(StringToSign);
MemoryStream stream = new MemoryStream(sha1Bytes);
byte[] …Run Code Online (Sandbox Code Playgroud) 我一直在想为什么constexr和virtual互相排斥,有人补充道:
... constexpr是关于编译时的执行; 如果我们在编译时执行该函数,我们显然也知道它在编译时所处理的数据类型,因此后期绑定显然不相关.
但是,即使在编译时,动态类型也可能与静态类型不同,并且可能存在需要动态类型的情况:
class A {
public:
/* virtual */ constexpr int foo() {
return 1;
}
};
class B : public A {
public:
constexpr int foo() {
return 2;
}
};
constexpr int foo(A &a) {
// The static type is fixed here.
// What if we want to call B::foo() ?
return a.foo();
}
int main() {
B b;
constexpr int c = foo(b);
return …Run Code Online (Sandbox Code Playgroud)