当前位置: 首页 > 知识库问答 >
问题:

您是否会将C RValue引用参数标记为const

燕宜修
2023-03-14

我一直在切换模板工厂函数来使用(和理解)d::f支持右值和移动语义学。我常用的模板类样板工厂函数总是将参数标记为const:

#include <iostream>
#include <utility>

template<typename T, typename U>
struct MyPair{
    MyPair(const T& t, const U& u):t(t),u(u){};

    T t;
    U u;
};

template<typename T, typename U>
std::ostream& operator<<(std::ostream& os, const MyPair<T,U>& pair){
    os << "(" << pair.t << ")=>" << pair.u;
    return os;
}

template<typename T, typename U>
MyPair<T,U> MakeMyPair(const T& t, const U& u){
    return MyPair<T,U>(t,u);
}

using namespace std;
int main(int argc, char *argv[]) {    

    auto no_forward = MakeMyPair(num, num);
    std::cout << no_forward << std::endl;

    auto no_forward2 = MakeMyPair(100, false);
    std::cout << no_forward2 << std::endl;
}

按预期编译。最初,我将MakeMyPair转换为以const形式传递参数,但这不会使用XCode 4.6在我的Mac上编译:

//$ clang --version
//Apple LLVM version 4.2 (clang-425.0.24) (based on LLVM 3.2svn)
//Target: x86_64-apple-darwin12.2.0
//Thread model: posix


template<typename T, typename U>
MyPair<T,U> MakeMyPair_Forward(const T&& t, const U&& u){
    return MyPair<T,U>(std::forward<const T>(t),std::forward<const U>(u));
}

int main(int argc, char *argv[]) { 
    int num = 37;
    auto anotherPair = MakeMyPair_Forward(num, true); //This won't work

    auto allRvalues = MakeMyPair_Forward(73, false);   //will compile 
    std::cout << allRvalues  << std::endl;
}

没有用于调用“MakeMyPair\U Forward”候选函数的匹配函数[具有T=int,U=bool]不可行:没有从“int”到“const int”的已知转换

这是有道理的http://en.cppreference.com/w/cpp/utility/forward它的状态常数是推导出来的,我传递的是左值。

  • 如果对wrapper()的调用传递了一个右值std::string,那么T将被推断为std::string(而不是std::string)

删除常量就像我想要的右值和左值一样。只有将右值作为类型传递才能使用MakeMyPair_Forward参数的const。

//This works for rvalues and lvalues
template<typename T, typename U>
MyPair<T,U> MakeMyPair_Forward(T&& t, U&& u){
    return MyPair<T,U>(std::forward<const T>(t),std::forward<const U>(u));
}

所以,问题来了。当作为参数传递时,将右值引用标记为const有意义吗?我不能改变右值,这只是暂时的。在完成并修复代码后,我有点惊讶它是用const编译的。为什么要将右值参数标记为常量?关键是只提供一个接受右值的API吗?如果是这样的话,您会使用类型特征来防止左值引用吗?https://stackoverflow.com/a/7863645/620304

谢谢

共有2个答案

庄子平
2023-03-14

另一个可能的用例,不是语言采用的,但可能是,是来自原始指针的智能指针构造函数,例如:

// this is NOT the actual ctor in the language but could have been
// see explanation in above link
unique_ptr(T* const&& p) : ptr{p} {}
令狐晟
2023-03-14

所以,问题来了。当作为参数传递时,将右值引用标记为const有意义吗?

这是C 11标准中的一个地方:

template <class T> reference_wrapper<T> ref(T&) noexcept;
template <class T> reference_wrapper<const T> cref(const T&) noexcept;
template <class T> void ref(const T&&) = delete;
template <class T> void cref(const T&&) = delete;

即Aconst T

这也可以用T来完成

 类似资料:
  • 是否可以以某种方式标记属性,以便在发送请求时可以理解在SwaggerUI中应设置哪个字段。 例如,我们有一个支付路由,它具有payment_type属性,可以保存paypal、credit_card、crypto等值。基于该字段,我们需要填充不同的属性,如下所示。 是否有可能以某种方式标记它们,以便将它们分组,例如对于加密加密货币,应该设置wallet_address,而对于银行转帐,应设置快速,

  • 问题内容: 只是看那里张贴的例子 如果您将meta标签保留在中,那么如何将这两个日期与他们的评论相关联? 这引起了混乱,我想知道如何正确进行。 问题答案: 如果一个元素 有一个属性和一个属性,并且 没有属性,没有属性,也没有属性, 那么将其包含在中是有效的。(如果该值为URL,则必须改用。) 为什么?因为微数据规范更改了HTML5。 (请注意,RDFa的也允许改变HTML5 在 某些情况下)。 如

  • 我正在使用Github Copilot生成要添加到ArrayList的整数,但出于某种原因,它在参数之前添加了 我已经使用Copilot一段时间了,但我从未遇到过这种情况。为什么会发生这种情况?

  • 我有一些麻烦与我的第一个Spring后端为Mongo DB。我创建了一个带有一些属性的组件类。其中之一是零件号,零件号应是唯一的。所以我设置了@Indexed(独特=真实)注释。 应用程序运行良好。但是如果我用postman测试endpoint,那么除了零件号之外,所有属性都会写入Mongo文档。PN始终是empyt。我不明白为什么。如果有人能帮我解决他的问题,我会很高兴的。 这是组件类 这是对路

  • 我有一个问题,我无法将任何参数传递到一个模态窗口(使用引导程序3),我尝试使用本链接中所述的解决方案,但我无法使其工作: 动态加载信息到Twitter引导模式 (解决方案kexxcream用户)。 我已经附上了代码(上面左边的代码帖子相同); JS代码: PHP代码(backend.PHP):

  • 您可以在 @ConversationScoped Bean 中注入的对话接口是否可以安全地标记瞬态(即 CDI 是否会在序列化期间处理它),或者我是否需要自定义读/写对象? FindBugs抱怨一个非暂时的不可序列化实例字段。