вызывающая версия is_const <> но для переменных вместо типов в одной строке - PullRequest
0 голосов
/ 21 марта 2020

Привет, я изучаю 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 , так это можно назвать одной строкой?

1 Ответ

1 голос
/ 21 марта 2020

Вы просто используете немного неправильный синтаксис здесь:

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 не является c членом 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;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...