我有两节课:
template <typename Tp>
class Model;
template <typename TMp>
class Mesh;
我需要
Model
来包含 Mesh
作为成员,但有以下限制:
如果是
Model<float>
,则该成员应该是 Mesh<float>
。 如果是 Model<double>
,则该成员可以是 Mesh<double>
或 Mesh<float>
。
我正在尝试使用概念来解决这个问题,到目前为止已经写过:
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;
};
这有效,我可以像这样使用它:
Mesh mesh;
Model model(mesh);
但是如果我想使用
Mesh<float>
和Model<double>
,我需要在实例化Model
时指定这两个模板参数,即:
Mesh<float> mesh;
Model<double,float> model(mesh);
为什么不能推导出
TMp
? 也就是说,为什么以下不起作用:
Mesh<float> mesh;
Model<double> model(mesh);
编译器不应该知道传递给构造函数的网格是
Mesh<float>
类型吗? 因此,TMp
不应该被推导为float
吗? 也许我正在追求一些无论如何都无法阅读的东西,这只是我第一次尝试实现这一点,当它不起作用时我感到很惊讶。
Model model(mesh);
利用类模板参数推导 (CTAD)。 Model<double> model(mesh);
没有。
CTAD,要么全有,要么全无。您不能显式指定某些模板参数并推导另一个。不过,您可以退回到函数模板参数推导,您可以明确指定一些参数,然后推导另一个。
您的代码无法编译(缺少包含),因此我将使用不同的示例。
#include <iostream>
#include <type_traits>
template <typename T>
struct Foo {};
template <typename T,typename U>
struct Bar {};
template <typename T,typename U>
Bar<T,U> make_bar(const Foo<U>&) { return {}; }
int main() {
Foo<int> x;
auto b = make_bar<float>(x);
std::cout << std::is_same_v<decltype(b),Bar<float,int>>;
}