[英]Trying to use std::add_const to turn T& into const T&
I have a T& which has a const and non-const version of a function. 我有一个T&具有const和非const版本的函数。 I want to call the const version of the function.
我想调用函数的const版本。 I try using std::add_const to turn T& into const T& but it doesn't work.
我尝试使用std :: add_const将T&转换为const T&但它不起作用。 What am I doing wrong and how can I fix it?
我做错了什么,我该如何解决?
Here is a simple example. 这是一个简单的例子。
void f(int&)
{
std::cout << "int&" << std::endl;
}
void f(const int&)
{
std::cout << "const int&" << std::endl;
}
int main()
{
int a = 0;
int& r = a;
f(static_cast<std::add_const<decltype (r)>::type>(r));
}
Output: int&
输出:
int&
Type traits are a very laborious way of approaching this. 类型特征是一种非常费力的方法来解决这个问题。 Simply use template type deduction:
只需使用模板类型扣除:
void f(int&)
{
std::cout << "int&" << std::endl;
}
void f(const int&)
{
std::cout << "const int&" << std::endl;
}
template<typename T>
const T& make_const(T& t) { return t; }
int main()
{
int a = 0;
int& r = a;
f(make_const(r));
}
References cannot be cv-qualified, so std::add_const
applied to a reference type leaves it unchanged. 引用不能是cv限定的,因此应用于引用类型的
std::add_const
会使其保持不变。 In this particular case you should just do 在这种特殊情况下你应该这样做
f(static_cast<const int&>(r));
but in general you will have to transform the reference type T
like this: 但一般来说,你必须像这样转换引用类型
T
:
template<typename T>
struct add_const_to_reference {
typedef T type;
};
template<typename T>
struct add_const_to_reference<T&> {
typedef const T& type;
};
template<typename T>
struct add_const_to_reference<T&&> {
typedef const T&& type;
};
std::add_const
does nothing for a reference, since a reference can't be const qualified, only what it references can be. std::add_const
对引用没有任何作用,因为引用不能是const限定的,只能引用它。
In your case, a simple solution is to make a const version: 在您的情况下,一个简单的解决方案是制作一个const版本:
int main()
{
int a = 0;
int& r = a;
const int &const_r = r;
f(const_r);
}
or if you don't want to specify an explicit type: 或者如果您不想指定显式类型:
int main()
{
int a = 0;
int& r = a;
const auto &const_r = r;
f(const_r);
}
If you just want to prevent treating an expression as mutable, you could use std::cref
: 如果您只是想防止将表达式视为可变,可以使用
std::cref
:
#include <functional>
int main()
{
int a = 0;
int& r = a;
f(std::cref(r));
}
Here cref
returns a std::reference_wrapper<const int>
struct, which implicitly converts back to const int&
. 这里
cref
返回一个std::reference_wrapper<const int>
结构,它隐式转换回const int&
。
If you want to actually do something with the corresponding reference-to-const-something type, either create your own trait as @Brian suggested, or use decltype
on your own wrapper function as @BenVoigt suggested, or you could do something like this if you really still want to take advantage of cref
: 如果你想用相应的reference-to-const-something类型做一些事情,或者按照@Brian的建议创建你自己的特性,或者在@BenVoigt建议的你自己的包装函数上使用
decltype
,或者你可以做这样的事情,如果你真的还想利用cref
:
int main()
{
int a = 0;
int& r = a;
using ConstRefT = decltype(std::cref(r))::type &;
}
The general answer to how to do manual overload resolution is to cast the function pointer, ie here static_cast<(void(*)(const int&)>(f)(r)
. Uhm, I hope I got the parentheses right. In this specific case you can alternatively just cast the argument, f( static_cast<const int&>( r ) )
, since static_cast
can do any implicit conversion. 如何进行手动重载解析的一般答案是转换函数指针,即这里
static_cast<(void(*)(const int&)>(f)(r)
。嗯,我希望我的括号是正确的。在特定情况下,你可以选择只抛出参数f( static_cast<const int&>( r ) )
,因为static_cast
可以进行任何隐式转换。
int main()
{
int a = 0;
int& r = a;
f(static_cast<int const&>(r));
}
If you want to generalize that by composing the standard library's type modifiers, then you can do it like this: 如果你想通过编写标准库的类型修饰符来概括它,那么你可以这样做:
f(static_cast<std::remove_reference<decltype(r)>::type const&>(r));
Since that's pretty ugly I recommend just defining a general const
-adder, or for an ad-hoc thing declaring a reference to const
locally and use that as argument. 由于这非常难看,我建议只定义一个通用的
const
-adder,或者用于在本地声明对const
的引用并将其用作参数的特殊事物。
A general const
-adder can go like this: 一般
const
-adder可以这样:
template< class Type >
auto const_ref( Type const& r ) -> Type const& { return r; }
const_cast
is what you need. const_cast
是你需要的。 See: http://www.cplusplus.com/doc/tutorial/typecasting/ 请参阅: http : //www.cplusplus.com/doc/tutorial/typecasting/
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.