如果模板参数很复杂,则在模板函数中应用 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.
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.