在一行中调用 is_const<> 的版本,但对于变量而不是类型

calling version of is_const<> but for variables instead of types, in one line

您好,我正在学习 C++,并且我阅读了 is_const 等类型特征。 is_const 可以像这样在一行中调用,

cout << is_const<double>::value << endl;

我做了自己的版本 is_const 但是为了测试一个变量是否是 const,它可以像这样使用,

#include<iostream>
using namespace std;

template<typename T>
  struct check_const {
    check_const(const T *x): val(std::true_type{})
    { }
    check_const(T *x) : val(std::false_type{})
    { }
    bool val;
};

int main() 
{
   const double pi= 3.14;
   check_const<double> r(&pi);
   cout <<  r.val << endl;    // returns 1
   double x= 2.7;
   check_const<double> s(&x);
   cout << s.val << endl;    // returns 0
   return(0);
}

我也想在一行中调用 check_const,但是编译器一直给我这样的错误

"typename not allowed" 

当我尝试称呼它时

cout << check_const<double> t(&pi)::val << endl;

如何更改check_const,使其可以一行调用?

您只是在此处使用了一个稍微错误的语法:

cout << check_const<double> t(&pi)::val << endl;

改为使用

cout << check_const<double>(&pi).val << endl; 

check_const<double> t(&pi) 是命名变量定义的语法,但表达式中不能有 declarations/definitions。

check_const<double>(&pi) 是创建未命名临时文件的语法,可以在表达式中完成。

那么你需要 . 而不是 ::,因为 valcheck_const.

的非静态成员

从 C++17 开始,您还可以编写:

cout << check_const(&pi).val << endl; 

并为您推导模板参数。


不过,所有这些都可以简化,因为您并没有真正使用 class。您可以将构造函数用作自由函数:

template<typename T>
constexpr bool check_const(const T *x) noexcept { return true; }

template<typename T>
constexpr bool check_const(T *x) noexcept { return false; }

( constexpr 使得在常量表达式中使用函数成为可能,但在其他方面不是必需的。类似地 noexcept 只是一个指示函数不会抛出异常,但是否则不需要。)

这可以更容易地用作

cout << check_const(&pi) << endl;

此外,使用引用代替指针:

template<typename T>
constexpr bool check_const(const T &x) noexcept { return true; }

template<typename T>
constexpr bool check_const(T &x) noexcept { return false; }

你可以写

cout << check_const(pi) << endl;