函数模板中的is_const <func-param>始终返回false

Mic*_*ann 3 c++ templates

是否可以将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
    ;
}
Run Code Online (Sandbox Code Playgroud)

我没有成功尝试过类似的各种版本:

template<typename T>
bool test(T x)
{
  return is_const<???>::value;
}
Run Code Online (Sandbox Code Playgroud)

我想确保我没有遗漏某些东西,写这样的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)
Run Code Online (Sandbox Code Playgroud)

Man*_*rse 6

在C++ 11中,这可以通过完美的转发右值引用来完成:

template<typename T>
bool test(T&& x)
{
    return std::is_const<typename std::remove_reference<T>::type>::value;
}
Run Code Online (Sandbox Code Playgroud)

在C++ 03中,您可以改为使用左值引用:

template<typename T>
bool test(T& x) {
    return boost::is_const<T>::value;
}
Run Code Online (Sandbox Code Playgroud)

两者之间的差异如下所示:

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
;
Run Code Online (Sandbox Code Playgroud)