#c #class #interface #shared-ptr #sfinae
#c #класс #интерфейс #общий -ptr #sfinae
Вопрос:
Я не могу понять, как я могу создать объект expr из double в expr.cpp досье.
expr_base:
Базовый класс всех выражений. Обратите внимание, что все классы выражений (включая эту базу) являются частными для реализации и не должны быть доступны для другого кода. Остальная часть программы должна использовать выражения только через expr
.
Этот подкласс std::enable_shared_from_this
позволяет получать shared_ptr для этого из метода.
выражение:
Обертка вокруг динамически выделяемых экземпляров expr_base . Этот тип имеет семантику значений, и поскольку все подклассы expr_base являются неизменяемыми, создаются мелкие копии.
Этот тип имеет перегруженные функции и операторы, так что построение выражений легко и читаемо.
ошибка:
error: no viable conversion from returned value of type 'typename enable_if<!is_array<number>::value,
shared_ptr<number> >::type' (aka 'std::__1::shared_ptr<exprs::number>') to function return type 'expr'
return std::make_shared<exprs::number>(n);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/..../expr.hpp(...): note: candidate constructor (the implicit copy constructor) not viable: no known conversion from 'typename enable_if<!is_array<number>::value, shared_ptr<number> >::type' (aka 'std::__1::shared_ptr<exprs::number>') to 'const expr amp;' for 1st argument
class expr final {
^
/.../expr.hpp:(...): note: candidate constructor (the implicit move constructor) not viable: no known conversion from 'typename enable_if<!is_array<number>::value, shared_ptr<number> >::type' (aka 'std::__1::shared_ptr<exprs::number>') to 'expr amp;amp;' for 1st argument
/.../expr.hpp:(...): note: candidate template ignored: requirement 'std::is_convertible<exprs::number *, const expr_base*>::value' was not satisfied [with T = exprs::number]
expr(std::shared_ptr<T> e): ptr(std::static_pointer_cast<const expr_base>(std::move(e))) {}
выражение hpp
...
class expr;
class expr_base: public std::enable_shared_from_this<expr_base>
{
friend class expr;
protected:
expr_base() = default;
public:
using variable_map_t = std::map<std::string, double>;
virtual ~expr_base() = default;
};
class expr final {
private:
using const_pointer = std::shared_ptr<const expr_base>;
public:
using variable_map_t = expr_base::variable_map_t;
template <typename T, typename = std::enable_if_t<std::is_convertible<T*, const expr_base*>::value>>
expr(std::shared_ptr<T> e): ptr(std::static_pointer_cast<const expr_base>(std::move(e))) {}
expr() = default;
static expr number(double n);
operator const_pointer const amp;() const {return ptr;}
const expr_base* operator->() const {assert(ptr.get() != nullptr); return ptr.get();}
private:
const_pointer ptr;
};
expr.cpp
...
#include "expr.hpp"
#include "expr_impl.hpp"
expr expr::number(double n) {
return std::make_shared<exprs::number>(n); // It doesn't work
}
expr_impl.hpp
...
#include "expr.hpp"
namespace exprs {
class number:expr_base {
private:
double num_;
public:
number(double num): num_(num) {};
};
}
Комментарии:
1.
class number:expr_base
должен бытьclass number: public expr_base