簡體   English   中英

std :: abs與std :: transform不起作用

[英]std::abs with std::transform not working

舉個例子:

#include <vector>
#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cmath>

void PrintVec(const std::vector<float>&);
int main(int argc, char * argv[]){

float vals[] = {-1.2,0.0,1.2};
std::vector<float> test(vals, vals + sizeof(vals) / sizeof(float));
std::vector<float> absTest(3);

std::transform(test.begin(), test.end(), absTest.begin(), std::abs<float>());

PrintVec(test);
PrintVec(absTest);

return 0;
}

void PrintVec(const std::vector<float> &vec){
for (unsigned int i = 0; i < vec.size(); ++i){
    std::cout << vec[i] << '\n';
}
return;
}

同時使用gcc 4.3.4和VS 2013會出現編譯器錯誤。 對於gcc:

testTransformAbs.cpp:15:錯誤:“浮動”之前的預期主表達式

對於VS 2013,其:

錯誤C2062:意外鍵入“浮動”

如果刪除<float>則會出現此錯誤:

testTransformAbs.cpp:15:錯誤:沒有匹配的函數可調用'abs()'/usr/include/stdlib.h:766:注意:候選對象是:int abs(int)/usr/include/c++/4.3/cstdlib :144:注意:long int std :: abs(long int)/usr/include/c++/4.3/cstdlib:175:注意:long long int __gnu_cxx :: abs(long long int)/usr/include/c++/4.3 / cmath:99:注意:double std :: abs(double)/usr/include/c++/4.3/cmath:103:注意:float std :: abs(float)/usr/include/c++/4.3/cmath:107 :注意:long double std :: abs(long double)

我可以創建自己的功能

float MyAbs(float f){
    return sqrt(f * f);
}

std::transform(test.begin(), test.end(), absTest.begin(), MyAbs);

一切正常。 cplusplus.com上的參考資料說,第四個輸入可以是一個UnaryOperation,其定義如下:

一元函數,將InputIterator指向的類型的一個元素作為參數,並返回一些可轉換為OutputIterator指向的類型的結果值。 這可以是一個函數指針或一個函數對象。

對我來說,這應該可以使用std::abs() 我也嘗試過fabs ,結果也一樣。 我想念什么?

std::abs是一個重載函數,而不是模板函數。 獲取指向函數的指針時,可以通過強制轉換來選擇特定的重載:

std::transform(test.begin(), test.end(), absTest.begin(),
    static_cast<float (*)(float)>(&std::abs));

或通過使用函數指針變量:

float (*fabs)(float) = &std::abs;
std::transform(test.begin(), test.end(), absTest.begin(), fabs);

請注意,我還刪除了abs后面的() ,因為這是一個函數,而不是需要實例化的類。

std::abs不是模板 標頭中以ac cmath標頭中的任何函數(如cmathcstdlib都沒有任何C ++功能(如模板),因為它們表示C標准庫。 std::abs也適用於整數類型。 您應該將std :: fabs用於浮點類型。

我不喜歡函數指針強制轉換,所以在這種情況下,我通常會寫一些如下的包裝器:

namespace hlp {
template <class T> struct iabs { 
    static_assert(std::is_integral<T>::value, "");
    T operator()(T const& t){ return std::abs(t); } 
};
template <class T> struct fabs { 
    static_assert(std::is_floating_point<T>::value, ""); 
    T operator()(T const& t){ return std::fabs(t); } 
};
}

您可以像在問題中使用std :: abs一樣使用這些包裝器。 當您嘗試將整數版本用於浮點類型時, static_assert會生成干凈的編譯器錯誤,反之亦然。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM