在C++中,我想专门化一个模板函数。到目前为止还不错
问题是,专门化我的模板的类型依赖于我无权访问的typedef。
目的说明
用户必须首先通过在模板中指定一些类型来为类Surface_mesh
定义typedef。
typedef CGAL::Surface_mesh<CGAL::Simple_cartesian<double>::Point_3> Mesh;
Mesh
可能会根据用户的需要而变化,但它始终具有以下类型定义:
- 网格::Face_index
- 网格::顶点索引
- 网格::边索引
现在我想写一个函数,它有不同的实现,取决于Face_index
、Vertex_index
或Edge_index
,但不取决于typedefMesh
。以下是用户如何使用它:
std::cout << foo<void>() << std::endl;
std::cout << foo<Mesh::Face_index>() << std::endl;
std::cout << foo<Mesh::Vertex_index>() << std::endl;
std::cout << foo<Mesh::Edge_index>() << std::endl;
>> "Default foo() called"
>> "foo() for Face_index called"
>> "foo() for Vertex_index called"
>> "foo() for Edge_index called"
我尝试过的
如果foo
可以访问Mesh
tyedef,那么第一个实现就可以工作,但事实并非如此:
template <typename EI> //for Element Index
std::string foo(void)
{
return "Default foo() called";
}
template <>
std::string foo<Mesh::Face_index>(void)
{
return "foo() for Face_index called";
}
...
所以我试过这样的方法,但它不起作用:
template <typename SM, typename EI> //for Surface Mesh and Element Index
std::string foo(void)
{
return "Default foo() called";
}
template <typename SM>
std::string foo<SM::Face_index>(void)
{
return "foo() for Face_index called";
}
...
问题
你知道是否可以做我想做的事,如果可以,如何做吗?或者你有网站的链接和解释可以帮助我吗?
编辑
以下是Surface_Mesh:的简化实现
namespace CGAL
{
// Implementation for Surface_mesh::Vertex_index
class SM_Vertex_index
{
//...
};
// Implementation of Surfae_mesh::Face_index
class SM_Face_index
{
//...
};
template <typename P>
class Surface_mesh
{
public:
typedef SM_Vertex_index Vertex_index;
typedef SM_Face_index Face_index;
//... (P is used in the code)
};
}
在CGAL中,Face_index
仅为SM_Face_idex
(typedef SM_Face_index Face_index;
)的typedef
,对于所有曲面网格也是如此,但创建文档时除外。
所以理论上你可以做:
template <typename T>
std::string foo(void)
{
return "Default foo() called";
}
template <>
std::string foo<SM_Face_index>(void)
{
return "foo() for Face_index called";
}
这将适用于当前的CGAL版本,但我在文档中没有看到任何内容,这将保证在未来会是这样。
问题是,文档声称Face_index
是在Mesh中定义的实际类,而不是独立于曲面网格类型的typedef
。
很难理解,但我认为下面的代码可能会对您有所帮助。它适用于vs 2017。
// cls && cl x.cpp /EHsc && x
#include <iostream>
template<typename P, typename V, typename D> class ObjA
{
public:
typedef P POSI;
typedef V VERT;
D extra;
};
typedef ObjA<int, double, float> Mesh;
template<typename T> void foo() noexcept
{
std::cout << __FUNCSIG__ << "n";
}
void foo() noexcept
{
std::cout << __FUNCSIG__ << "n";
}
int main()
{
foo<Mesh::POSI>(); // void __cdecl foo<int>(void) noexcept
foo<Mesh::VERT>(); // void __cdecl foo<double>(void) noexcept
foo(); // void __cdecl foo(void) noexcept
return 0;
}