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

Apply std::conj in template function if template argument is complex

TL;DR 假设我有一个带有模板参数 T 的函数,它接受 std::vector<T>& 作为输入(见下文),我想要共轭此向量,如果 T 是复数类型。我该怎么做?

我试过的方法之后,我知道我可以用

检查一个类型是否复杂
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 没有为非复杂类型定义。有什么设计可以满足我的要求吗?

您正在使用 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); });
}

这是一个demo

在c++11中,对于类型为[=30=的情况,可以使用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); });
}

这是一个demo.