Reputation: 775
In C++ I want to specialize a templated function. So far so good.
The problem is that the type that specialize my template depends on a typedef to which I don't have access.
The user must first define a typedef for the class Surface_mesh
by specifying some types in the template.
typedef CGAL::Surface_mesh<CGAL::Simple_cartesian<double>::Point_3> Mesh;
Mesh
may vary according to the user's needs, but it will always have the following typedef:
Now I want to write a function that has a different implementation depending on Face_index
, Vertex_index
or Edge_index
but not depending on the typedef Mesh
.
Here's how the user could use it:
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"
This first implementation work if foo
had access to the Mesh
tyedef, but this is not the case:
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";
}
...
So I have tried something like that, but it doesn't work:
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";
}
...
Do you know if it is possible to do what I want, and if so how to do it or do you have links to sites with explanations that could help me?
Here is a simplified implementation of 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)
};
}
Upvotes: 1
Views: 186
Reputation: 40842
In CGAL Face_index
is - except for the case when the documentation is created - just a typedef
for SM_Face_idex
(typedef SM_Face_index Face_index;
) and the same for all surface meshes.
So theoretically you could just do:
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";
}
This would work for the current CGAL versions, but I don't see anything in the documentation, that this will be guaranteed to be that way in the future.
The problem is that the documentation claims that Face_index
is an actual class defined within Mesh and not that it is a typedef
of a type independent of the surface mesh.
Upvotes: 2
Reputation: 128
It is hard to get your mind, but I think the follow code may help you. It works in 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;
}
Upvotes: 1