Как вы используете свойства типа для условной компиляции?
Я пытаюсь написать код здесь, но используя возможности С++ 11 без Boost.
Работая с в этом примере, я попытался определить условную компиляцию response_trait
и basee по результату признака. Как я могу сделать эту работу?
#include <vector>
using namespace std ;
struct Vector{ float x,y,z ; } ;
struct Vertex { Vector pos ; } ;
struct VertexN { Vector pos, normal ; } ;
struct Matrix {} ;
template <typename T>
struct response_trait {
static bool const has_normal = false;
} ;
template <>
struct response_trait<VertexN> {
static bool const has_normal = true;
} ;
template <typename T>
struct Model
{
vector<T> verts ;
void transform( Matrix m )
{
for( int i = 0 ; i < verts.size() ; i++ )
{
#if response_trait<T>::has_normal==true
puts( "Has normal" ) ;
// will choke compiler if T doesn't have .normal member
printf( "normal = %f %f %f\n", verts[i].normal.x, verts[i].normal.y, verts[i].normal.z ) ;
#else
puts( "Doesn't have normal" ) ;
printf( "pos = %f %f %f\n", verts[i].pos.x, verts[i].pos.y, verts[i].pos.z ) ;
#endif
}
}
} ;
int main()
{
Matrix m ;
Model<Vertex> model ;
model.verts.push_back( Vertex() ) ;
model.transform( m ) ;
Model<VertexN> modelNormal ;
modelNormal.verts.push_back( VertexN() ) ;
modelNormal.transform( m ) ;
}
Ответы
Ответ 1
Вы можете попробовать что-то вроде этого:
void transform_impl(Matrix const & m, std::true_type const &)
{
// has normal
}
void transform_impl(Matrix const & m, std::false_type const &)
{
// doesn't have normal
}
template <typename T>
void transform(Matrix const & m)
{
transform_impl(m, response_trait<T>());
}
Вам просто нужно немного изменить свой признак:
#include <type_traits>
template <typename> struct response_trait : std::false_type { };
template <> struct response_trait<VertexN> : std::true_type { };
Ответ 2
Вот альтернативное решение, если ваш код можно вводить в функции, не делая ваш дизайн громоздким (например, когда вам нужен доступ к множеству переменных-членов вашего объекта). Конечно, иногда желательно специализироваться на всем классе.
#include <vector>
#include <stdio.h>
using namespace std ;
struct Vector{ float x,y,z ; } ;
struct Vertex { Vector pos ; } ;
struct VertexN { Vector pos, normal ; } ;
struct Matrix {} ;
template <typename T>
void printVertex(T vert)
{
printf( "Doesn't have normal" ) ;
printf( "pos = %f %f %f\n", vert.pos.x, vert.pos.y, vert.pos.z ) ;
}
template <>
void printVertex(VertexN vert)
{
printf( "Has normal" ) ;
printf( "normal = %f %f %f\n", vert.normal.x, vert.normal.y, vert.normal.z ) ;
}
template <typename T>
struct Model
{
vector<T> verts ;
void transform( Matrix m )
{
for( int i = 0 ; i < verts.size() ; i++ )
{
printVertex(verts[i]);
}
}
} ;
int main()
{
Matrix m ;
Model<Vertex> model ;
model.verts.push_back( Vertex() ) ;
model.transform( m ) ;
Model<VertexN> modelNormal ;
modelNormal.verts.push_back( VertexN() ) ;
modelNormal.transform( m ) ;
}