0

嗨,我正在学习 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,以便可以在一行中调用它?

4

1 回答 1

1

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

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

而是使用

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

check_const<double> t(&pi)是命名变量定义的语法,但不能在表达式中包含声明/定义。

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

然后你需要.代替::,因为val是 的非静态成员check_const

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

cout << check_const(&pi).val << 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; }

(这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;
于 2020-03-21T20:20:37.093 回答