C++ 尝试使用std::add_const打开T&;进入常数T&;

C++ 尝试使用std::add_const打开T&;进入常数T&;,c++,C++,我有一个T&它有一个函数的常量和非常量版本。我想调用函数的const版本。我尝试使用std::add_const将T&转换为const T&但它不起作用。我做错了什么?我该如何修复它 下面是一个简单的例子 void f(int&) { std::cout << "int&" << std::endl; } void f(const int&) { std::cout << "const int&" <&l

我有一个T&它有一个函数的常量和非常量版本。我想调用函数的const版本。我尝试使用std::add_const将T&转换为const T&但它不起作用。我做错了什么?我该如何修复它

下面是一个简单的例子

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));
}
void f(int&)
{

std::cout
std::add_const
对引用不起任何作用,因为引用不能是const限定的,只能是它引用的内容

在您的情况下,一个简单的解决方案是制作常量版本:

int main()
{
    int a = 0;
    int& r = a;
    const int &const_r = r;
    f(const_r);
}
或者,如果不想指定显式类型:

int main()
{
    int a = 0;
    int& r = a;
    const auto &const_r = r;
    f(const_r);
}

const_cast
是您所需要的。
请参阅:

引用不能是cv限定的,因此应用于引用类型的
std::add_const
会使其保持不变。在这种情况下,您只需执行以下操作即可

f(static_cast<const int&>(r));

类型特征是一种非常费力的方法。只需使用模板类型推断:

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));
}
void f(int&)
{

std::cout如果您只是想防止将表达式视为可变的,可以使用:

如何进行手动重载解析的一般答案是强制转换函数指针,即在这里
static\u cast(f)(r)
。嗯,我希望括号是正确的。在这种特定情况下,您可以选择强制转换参数
f(static\u cast(r))
,因为
static\u cast
可以进行任何隐式转换

int main()
{
    int a = 0;
    int& r = a;
    f(static_cast<int const&>(r));
}

这是一个隐式转换,不需要强制转换。我想我更喜欢
const T&
而不是
const T&
,因为后者完全没有意义。但是如果你想
make_const(1)
工作,就添加一个重载。与其添加重载,不如添加
const
@aschep no make const,在这种情况下,只需f(1)通过编写
和make_const(1)
,或者使用我更喜欢的命名
和const_ref(1),它将提高可用性
。例如,为C函数提供一个参数。@阿尔夫:你知道有多少C API的参数类型为
const int*
?如果它是
const void*
,那么我想控制该类型,而不是让它隐含在文本中。例如,
&implicit\u cast(1)
看起来不错。相关:如果函数没有重载,您只是在函数指针类型之间执行了C样式转换。这真是个坏主意。(
boost::implicit_cast
或者初始化这样做是安全的)@BenVoigt:re“C样式转换”,你可以使用一个
static\u cast
。我更新了答案以向你展示。抱歉,我写这篇文章时时间不多。
#include <functional>

int main()
{
    int a = 0;
    int& r = a;
    f(std::cref(r));
}
int main()
{
    int a = 0;
    int& r = a;
    using ConstRefT = decltype(std::cref(r))::type &;
}
int main()
{
    int a = 0;
    int& r = a;
    f(static_cast<int const&>(r));
}
f(static_cast<std::remove_reference<decltype(r)>::type const&>(r));
template< class Type >
auto const_ref( Type const& r ) -> Type const& { return r; }