9

ここのようなコードを書こうとしていますが、Boost なしで C++11 の機能を使用しています。

このresponse_traitに基づいて、特性の結果に基づく条件付きコンパイルを定義しようとしました。どうすればこれを機能させることができますか?

#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 ) ;
}
4

2 に答える 2

16

あなたはこのようなことを試すことができます:

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 { };
于 2012-12-09T12:55:21.880 に答える
1

設計を煩雑にせずにコードを関数に入れることができる場合 (たとえば、オブジェクトの多数のメンバー変数にアクセスする必要がある場合) の代替ソリューションを次に示します。もちろん、クラス全体を専門化することが望ましい場合もあります。

#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 ) ;
}
于 2012-12-09T13:28:28.253 に答える