【发布时间】:2021-07-31 08:29:45
【问题描述】:
假设我有两个概念:
struct Vector3 {float x; float y; float z;};
template<typename T> concept ImplementsMeshGetters = requires(T a, uint index)
{
{ a.Position(index) }->std::convertible_to<Vector3>;
};
template<typename T> concept HasMeshMemberArrays = requires(T a, uint index)
{
{ a.positions[index] }->std::convertible_to<Vector3>;
};
我创建了一个模板类,它受任一者的约束:
template<typename MeshType>
requires(ImplementsMeshGetters<MeshType> || ImplementsMeshGetters<MeshType>)
class Mesh
{
Vector3 GetPosition(uint i);
};
我想要 3 个版本的函数 GetPosition 专门化,一个用于第一个概念,一个用于第二个概念,一个用于以防编译器不知何故混淆,这会引发错误以提醒用户该类不是' t 编译正确。
我试过了:
template<ImplementsMeshGetters MeshType>
Eigen::Vector3f AnimationMesh<MeshType>::GetPosition(uint i)
{
return mesh.Position(i);
};
template<HasMeshMemberArrays MeshType>
Eigen::Vector3f AnimationMesh<MeshType>::GetPosition(uint i)
{
return mesh.positions[i];
}
template<> Eigen::Vector3f AnimationMesh<typename T>::GetPosition(uint i)
{
Assert(
false,
"Somehow the mesh doesn't obey either of it's constraints. Your compiler "
"is likely broken.");
return {0, 0, 0};
}
但它无法编译,因为我正在重新定义相同的符号。
我可以这样做:
template<typename MeshType> Vector3 AnimationMesh<MeshType>::GetPosition(uint i)
{
if constexpr(ImplementsMeshGetters<MeshType>)
{ //
return mesh.Position(i);
}
else if constexpr(HasMeshMemberArrays<MeshType>)
{
return mesh.positions[i];
}
else
constexpr
{
Assert(
false,
"Somehow the mesh doesn't obey either of it's constraints. Your compiler "
"is likely broken.");
return {0, 0, 0};
}
};
但这比我可以实例化模板有点丑。
【问题讨论】:
-
这与试图特化模板类的方法没有什么不同:你不能,你必须首先特化模板。通常的解决方案是让方法使用辅助类重新调用适当的方法,然后专门化辅助类。
-
猜猜我将不得不采用第二种解决方案
标签: c++ templates template-meta-programming c++20 c++-concepts