I have two classes:
template <typename Tp>
class Model;
template <typename TMp>
class Mesh;
I need Model
to contain Mesh
as a member, but with the following constraints:
If Model<float>
, the member should be Mesh<float>
. If Model<double>
, the member can be either Mesh<double>
or Mesh<float>
.
I am trying to use concepts to address this, and have so far written:
template <typename Tp, typename TMp>
concept validMesh = requires (Tp model, TMp mesh)
{
std::floating_point<Tp>&& std::floating_point<TMp> && (std::same_as<Tp,TMp> || std::same_as<TMp, float>);
};
template <typename TMp>
requires std::floating_point<TMp>
class Mesh {
public:
Mesh() = default;
};
template <typename Tp=float , typename TMp=Tp>
requires validMesh<Tp,TMp>
class Model {
public:
Model(Mesh<TMp> mesh) : mesh{ mesh } { };
private:
Mesh<TMp> mesh;
};
This works, and I can use it like:
Mesh mesh;
Model model(mesh);
But if I want to use Mesh<float>
and Model<double>
, I need to specify both template parameters when instantiating Model
, that is:
Mesh<float> mesh;
Model<double,float> model(mesh);
Why is it not capable of deducing TMp
? That is to say, why doesn’t the following work:
Mesh<float> mesh;
Model<double> model(mesh);
Shouldn’t the compiler know that the mesh being passed into the constructor is of type Mesh<float>
? And thus, shouldn’t TMp
be deducible as float
? Perhaps I’m pursuing something that would be unreadable anyways, it was just my first attempt at implementing this, and I was surprised when it did not work.