为什么std::remove_const
未将const T&
转换为T&
?这个公认的相当人为的例子证明了我的问题:
#include <type_traits>
int main()
{
int a = 42;
std::remove_const<const int&>::type b(a);
// This assertion fails
static_assert(
!std::is_same<decltype(b), const int&>::value,
"Why did remove_const not remove const?"
);
return 0;
}
上述情况很容易解决,因此对于上下文,请想象以下内容:
#include <iostream>
template <typename T>
struct Selector
{
constexpr static const char* value = "default";
};
template <typename T>
struct Selector<T&>
{
constexpr static const char* value = "reference";
};
template <typename T>
struct Selector<const T&>
{
constexpr static const char* value = "constref";
};
int main()
{
std::cout
<< Selector<typename std::remove_const<const int&>::type>::value
<< std::endl;
return 0;
}
在上面的示例中,我希望显示reference
,而不是constref
。
答案 0 :(得分:14)
std::remove_const
删除顶级 const
- 资格。在const T&
中,等同于T const&
,限定不是顶级的:事实上,它不适用于引用本身(这将毫无意义,因为引用根据定义是不可变的),但是引用的类型。
C ++ 11标准第20.9.7.1段中的表52规定了std::remove_const
:
除了
T
之外,成员typedef类型的名称应与remove_const<const volatile int>::type
相同 已删除任何顶级 const限定符。 [示例:volatile int
评估为remove_const<const int*>::type
,而const int*
评估 到const
。 - 结束示例]
要剥离std::remove_reference
,您首先必须应用std::remove_const
,然后应用std::add_lvalue_reference
,然后(如果需要)应用{{1 (或在你的情况下适当的任何东西)。
注意:在评论中提及Xeo时,您可以考虑using an alias template such as Unqualified
执行前两个步骤,即删除引用,然后删除{{ 1}} - (和const
)资格。