C++模板:计算值并在编译时做出决策

Chr*_*ris 3 c++ templates

假设您有一个具有模板长度和类型的矢量类 - 即vec<2,float>.这些也可以嵌套 - vec<2,vec<2,vec<2,float> > >或者vec<2,vec<2,float> >.您可以计算嵌套其中一个向量的深度如下:

template<typename T>
inline int depth(const T& t) { return 0; }
template<int N, typename T>
inline int depth(const vec<N,T>& v) { return 1+depth(v[0]); }
Run Code Online (Sandbox Code Playgroud)

麻烦的是你不知道它在运行时有多深,但你可能需要知道在comile-time的深度才能做到这样的事情:

// Do this one when depth(v1) > depth(v2)
template<int N, typename T, int M, typename U>
inline vec<N,T> operator +(const vec<N,T>& v1, const vec<M,U>& v2) {
    return v1 + coerce(v2,v1);
}
// Do this one when depth(v1) < depth(v2)
template<int N, typename T, int M, typename U>
inline vec<M,U> operator +(const vec<N,T>& v1, const vec<M,U>& v2) {
    return coerce(v1,v2) + v2;
}
Run Code Online (Sandbox Code Playgroud)

你不能只是抛出一个"if"语句,因为(a)更深入会影响返回类型,而(b)coerce()会在你试图将嵌套向量强制转换为嵌套较少的向量时生成构建错误.

有可能做这样的事情还是我被推到了C++模板的极限?

Joh*_*itb 5

这完全有可能.试试这个例子

template<int N, typename T, int M, typename U>
inline typename enable_if<is_deeper<T, U>::value, vec<N,T> >::type 
operator +(const vec<N,T>& v1, const vec<M,U>& v2) {
    return v1 + coerce(v2,v1);
}

template<int N, typename T, int M, typename U>
inline typename enable_if<is_deeper<U, T>::value, vec<M,U> >::type 
operator +(const vec<N,T>& v1, const vec<M,U>& v2) {
    return coerce(v1,v2) + v2;
}
Run Code Online (Sandbox Code Playgroud)

哪里is_deeper是一样的东西

/* BTW what do you want to do if none is deeper? */
template<typename T, typename U>
struct is_deeper { static bool const value = false; };

template<typename T, int N, typename U>
struct is_deeper<vec<N, U>, T> { 
  static bool const value = true;
};

template<typename T, int N, typename U>
struct is_deeper<T, vec<N, U> > { 
  static bool const value = false;
};

template<typename T, int N, int M, typename U>
struct is_deeper<vec<M, T>, vec<N, U> > : is_deeper<T, U> 
{ };
Run Code Online (Sandbox Code Playgroud)

  • 有时我使用`mpl :: true_`作为`struct is_deeper <vec <N,U>,T>:mpl :: true_ {};`和false同样 (2认同)