提问者:小点点

如果模板参数复杂,则在模板函数中应用std::conj


tl;dr假设我有一个带有模板参数t的函数,它以std::vector作为输入(见下文),如果t是一个复杂类型,我想要共轭这个向量。 我怎么能那么做?

我在https://stackoverflow.com/a/30737105/5913047之后所做的尝试,我知道我可以用

template<class T> struct is_complex : std::false_type {};
template<class T> struct is_complex<std::complex<T>> : std::true_type {};

所以我试着:

template<typename T>
void MyFunction(std::vector<T>& MyVector){
    // do something
    if (is_complex<T>()){
       std::transform(MyVector.begin(), MyVector.end(), MyVector.begin(),[](T&c){return std::conj(c););
    }
}

但是,如果我将此函数用于非复杂类型,编译器会说conj不是为非复杂类型定义的。 是不是有些设计能做到我想要的?


共1个答案

匿名用户

您使用的是if语句。 这要求if分支中的代码是可编译的,即使您不需要执行它。

在C++17中,要有条件地编译一段代码,可以像这样使用if constexpr:

if constexpr (is_complex<T>()) {
 //^^^^^^^^^   
    std::transform(MyVector.begin(), MyVector.end(), MyVector.begin(),[](T&c){ return std::conj(c); });
}

这是一个演示。

在C++11中,可以使用std::enable_if为类型不复杂的情况编写重载,如下所示:

template<typename T, typename std::enable_if<!is_complex<T>::value, int>::type = 0>
void MyFunction(std::vector<T>& MyVector){
    // do something
}

template<typename T,  typename std::enable_if<is_complex<T>::value, int>::type = 0>
void MyFunction(std::vector<T>& MyVector){
    // do something
    std::transform(MyVector.begin(), MyVector.end(), MyVector.begin(),[](T&c){ return std::conj(c); });
}

这是个演示。