I have a straightforward and functional PIMPLed class hierarchy that I cannot succeed in templating :
template <class T>
class Constraint {
protected:
//! Base class for constraint implementations
class Impl {
public:
virtual ~Impl() = default;
//! Tests if params satisfy the constraint
virtual bool test(const std::vector<double>& params) const = 0;
//! Returns upper bound for given parameters
virtual std::vector<double> upperBound(const std::vector<double>& params) const {
return std::vector<double>(params.size(),
std::numeric_limits<std::vector<double>::value_type>::max());
}
//! Returns lower bound for given parameters
virtual std::vector<double> lowerBound(const std::vector<double>& params) const {
return std::vector<double>(params.size(),
-std::numeric_limits < std::vector<double>::value_type > ::max());
}
};
std::shared_ptr<Impl> impl_;
public:
bool empty() const { return !impl_; }
bool test(const std::vector<double>& p) const { return impl_->test(p); }
std::vector<double> upperBound(const std::vector<double>& params) const {
std::vector<double> result = impl_->upperBound(params);
return result;
}
std::vector<double> lowerBound(const std::vector<double>& params) const {
std::vector<double> result = impl_->lowerBound(params);
return result;
}
double update(std::vector<double>& p, const std::vector<double>& direction, double beta) const;
Constraint(std::shared_ptr<Impl> impl = std::shared_ptr<Impl>());
};
//! No constraint
template <class T>
class NoConstraint : public Constraint<T> {
private:
class Impl final : public Constraint<T>::Impl {
public:
bool test(const std::vector<double>&) const override { return true; }
};
public:
NoConstraint() : Constraint<T>(std::shared_ptr<Constraint<T>::Impl>(new NoConstraint<T>::Impl)) {}
};
See
https://godbolt.org/z/G31ac4scz
for immediate use.
Namely the error is :
<source>: In constructor 'NoConstraint<T>::NoConstraint()':
<source>:55:71: error: type/value mismatch at argument 1 in template parameter list for 'template<class _Tp> class std::shared_ptr'
55 | NoConstraint() : Constraint<T>(std::shared_ptr<Constraint<T>::Impl>(new NoConstraint<T>::Impl)) {}
| ^
<source>:55:71: note: expected a type, got 'Constraint<T>::Impl'
Compiler returned: 1
I should mention that this is with x86-64 gcc from latest trunk, while I don't have that error with latest msvc compiler. Still I don't understand this "template deduction" failure.