是否可以将is_const
表达式转换为test
函数,或者这是不可能的,因为在模板类型推导期间会忽略顶级cv-qualifieres?
int main()
{
using std::is_const;
const int x = 0;
int y = 0;
// move to "bool test()"
std::cout
<< "main, x: " << is_const<decltype(x)>::value << "\n" // true
<< "main, y: " << is_const<decltype(y)>::value << "\n" // false
;
std::cout
<< "test, x: " << test(x) << "\n" // false, I wanted true
<< "test, y: " << test(y) << "\n" // false
;
}
我尝试了类似于以下各种版本的失败:
template<typename T>
bool test(T x)
{
return is_const<???>::value;
}
我想确保我没有遗漏某些东西,并且编写这样的test
函数确实是不可能的。 (如果有可能的话,我也想知道C ++ 03版本是否可行。)
感谢您的考虑
更新
由于Mankarse,我知道在rvalue引用的情况下类型推导是不同的:
template<typename T> void t1(T x);
template<typename T> void t2(T& x);
template<typename T> void t3(T&& x);
const int x = 42;
int y = 0;
t1(x); // T = int: t1<int>(int x)
t1(y); // T = int: t1<int>(int x)
t2(x); // T = const int: t2<const int>(const int& x)
t2(y); // T = int: t2<int>(int& x)
t3(x); // T = const int&: t3<const int&>(const int& && x)
t3(y); // T = int&: t3<int&>(int& && x)
答案 0 :(得分:6)
在C ++ 11中,这可以通过完美的转发右值引用来完成:
template<typename T>
bool test(T&& x)
{
return std::is_const<typename std::remove_reference<T>::type>::value;
}
在C ++ 03中,您可以改为使用左值引用:
template<typename T>
bool test(T& x) {
return boost::is_const<T>::value;
}
两者之间的差异如下所示:
typedef int const intc;
intc x = intc();
int y = int();
std::cout // C++11 C++03
<< "x: " << test(x) << "\n" // 1 1
<< "y: " << test(y) << "\n" // 0 0
<< "move(x): " << test(std::move(x)) << "\n"// 1 1 (when compiled as C++11)
<< "move(y): " << test(std::move(y)) << "\n"// 0 compilation error
<< "intc{}: " << test(intc()) << "\n" // 0 compilation error
<< "int{}: " << test(int()) << "\n" // 0 compilation error
;