代码之家  ›  专栏  ›  技术社区  ›  quant_dev

返回C++模板类的具体实例化的工厂方法

  •  1
  • quant_dev  · 技术社区  · 17 年前

    template <unsigned int N>
    class StaticVector {
    // stuff
    };
    

    如何在此类中声明和定义返回StaticVector的静态工厂方法<3>物体

    StaticVector<3> create3dVec(double x1, double x2, double x2);
    

    ?

    4 回复  |  直到 17 年前
        1
  •  1
  •   Steve Jessop    17 年前

    “如何在此类中声明和定义”

    在哪个班?您定义的是类模板,而不是类。不能调用类模板本身的静态函数,必须调用作为真实类一部分的特定版本的静态函数。

    如果前者:

    
      template <unsigned int N>
      struct SV {
        int contents[N];
        static SV<3> get3dVec(int x, int y, int z) {
          SV<3> v;
          v.contents[0] = x;
          v.contents[1] = y;
          v.contents[2] = z;
          return v;
        }
      };
    
      int main() {
        SV<3> v = SV<1>::get3dVec(1,2,3);
      }
    

    对我有用。

    如果是后者(您只希望get3dVec成为SV<3>的成员,而不是所有SV<whatever>),则需要模板专业化:

    
      template <unsigned int N>
      struct SV {
        int contents[N];
      };
    
      template<>
      struct SV<3> {
        int contents[3]; // must be re-declared in the specialization
        static SV<3> get3dVec(int x, int y, int z) {
          SV<3> v;
          v.contents[0] = x;
          v.contents[1] = y;
          v.contents[2] = z;
          return v;
        }
      };
    
      int main() {
        SV<3> v = SV<1>::get3dVec(1,2,3); // compile error
        SV<3> v = SV<3>::get3dVec(1,2,3); // OK
      }
    

        2
  •  0
  •   Klaim    17 年前

    template< unsigned int SIZE >
    StaticVector< SIZE > createVec( const std::tr1::array< double, SIZE >& values )
    { 
         StaticVector< SIZE > vector;
         for( int i = 0; i < values.size(); ++i ) // here assuming that StaticVector have [] operator to access values on write
         {
             vector[i] = values[i];
         }
    
         return vector;
    }
    

    ... 或者一种变体肯定会起作用。(没有测试)

    用途如下:

    std::tr1::array< double, 3 > vectorValues = { 10.0, 10.0, 42.0 };
    
    StaticVector<3> vector1 = createVector( vectorValues ); // if the compiler can guess the size from the array information
    StaticVector<3> vector2 = createVector<3>( vectorValues ); // if you have to specify the size
    

    另一种方法是用基本数组替换std::tr1::array,但使用原始数组的风险由您自己承担:)

        3
  •  0
  •   Community Mohan Dere    9 年前

    首先,我相信你本来是想回来的

    StaticVector<N>
    

    template <unsigned int N>
    class StaticVector {
    public:
        // because of the injected class-name, we can refer to us using
        // StaticVector . That is, we don't need to name all template
        // parameters like StaticVector<N>.
        static StaticVector create3dVec(double x1, double x2, double x2) {
            // create a new, empty, StaticVector
            return StaticVector();
        }
    
    };
    

    StaticVector<4>::create3dVec 不起作用。您可以使用所描述的技术来实现这一点 here .

    createVec 这适用于任何大小,您可能希望用数组替换参数。您也可以这样做,但这是高级的,需要在boost::preprocessor中应用一些宏技巧。我想这不值得。下一个C++版本将提供 为此目的。无论如何,考虑使用这样的东西:

    我认为这只会使事情变得不必要的复杂。一个快速的解决方案是使用boost::fusion::vector,将其放入类模板中,而不是上面的版本:

    static StaticVector createVec(double (&values)[N]) {
        // create a new, empty, StaticVector, initializing it
        // with the given array of N values.
        return StaticVector();
    }
    

    你可以和我一起用

    double values[3] = {1, 2, 3};
    StaticVector<3> v = StaticVector<3>::createVec(values);
    

    请注意,它通过引用接受数组。你不能给它一个指针。这是因为它与参数的使用相匹配:另一种方法不能提供更少或更多的参数。它还将保护您免受以下情况的影响:

    // oops, values is a null pointer!
    StaticVector<3> v = StaticVector<3>::createVec(values);
    

    数组永远不能是空指针。当然,如果愿意,可以随时将数组参数更改为指针。这只是我个人的喜好:)

        4
  •  0
  •   quant_dev    17 年前

    我想返回一个3元素向量。原因是这些向量应该是几何实体,所以N不需要太高(我不是弦物理学家,所以我不在11维空间中工作)。我想创建一个模板,以避免重复代码,但将一维、二维和三维向量保持为单独的类型。

    推荐文章