Вы просто используете немного неправильный синтаксис здесь:
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;