clangとgccのテンプレートパラメータがどのように解決されるかには多少の違いがあるようです。あるいは、clangはatan2
とpow
バイナリ操作を考慮していないかもしれませんが、gccはバイナリ操作を考慮しません。引数atan2/powでstd :: transformsをコンパイルするのがclangで失敗しますが(gccで動作します)
以下のコードサンプルは、自分自身ではあまり意味がなく、最小限の方法で問題を再現していません:
#include <vector>
#include <algorithm>
#include <cmath>
#define TRANSFORM_MACRO(op,func) \
template<class T> \
std::vector<T> &trans_##op(const std::vector<T> &a, const std::vector<T> &b, std::vector<T> &dst) { \
std::transform(a.begin(), a.end(), b.begin(), dst.begin(), func); \
return dst; \
} \
template std::vector<float> &trans_##op(const std::vector<float>&, const std::vector<float>&, std::vector<float>&); \
template std::vector<double> &trans_##op(const std::vector<double>&, const std::vector<double>&, std::vector<double>&);
TRANSFORM_MACRO(arctan2, ::atan2)
int main() {
return 0;
}
をGCC(5.4 Ubuntuの、6.0 OSXシエラ)でこれをコンパイルするには、正常に動作します。打ち鳴らす(900.0.37)を使用すると、次のエラーが返されます。
/Users/alneuman/CLionProjects/temptest/main.cpp:15:1: error: no matching function for call to 'transform'
TRANSFORM_MACRO(arctan2, atan2)
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/Users/.../CLionProjects/temptest/main.cpp:9:7: note: expanded from macro 'TRANSFORM_MACRO'
std::transform(a.begin(), a.end(), b.begin(), dst.begin(), func); \
^~~~~~~~~~~~~~
/Users/.../CLionProjects/temptest/main.cpp:15:1: note: in instantiation of function template specialization 'trans_arctan2<float>' requested here
/Users/.../CLionProjects/temptest/main.cpp:12:34: note: expanded from macro 'TRANSFORM_MACRO'
template std::vector<float> &trans_##op(const std::vector<float>&, const std::vector<float>&, std::vector<float>&); \
^
<scratch space>:22:1: note: expanded from here
trans_arctan2
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1/algorithm:1932:1: note: candidate template ignored: couldn't infer template argument '_BinaryOperation'
transform(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2,
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1/algorithm:1922:1: note: candidate function template not viable: requires 4 arguments, but 5 were provided
transform(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _UnaryOperation __op)
問題は、GCCのみの仕様を必要としないため、一つの定義を持っているとatan2
とpow
の組み込みバージョンを使用していることのようです。 Clangは複数の定義を持つstd :: atan2/powに落ちているようです。 Clangには__builtin_atan2
がありますが、コンパイラの出力を考慮して直接呼び出さなければならないため、これをstd::transform
と一緒に使用することはできません。
'std :: atan2;を使用すると、gccで問題が再現されます。 atan2がオーバーロードされているので、必要なオーバーロードを指定する必要があります。 –
@MarcGlisse:これは私が正しい方向に向いていると思う。元のコードでは、 'std :: transform'はマクロの一部です(私はそれに応じて例を更新しました)。 'static_cast(func)'のようなテンプレートにfuncの関数ポインタをキャストすると、コードはclangでは動作しますが、gccでは動作しません。 GCCは、 'float(*)(float、float)'と入力すると 'double(double、double)'型の無効なstatic_castについて文句を言います。 GCCがatan2の浮動小数点バージョンを知らないように見えます。 –
aleneum
atan2を 'std :: atan2'に置き換えます.gccは浮動小数点バージョンを認識します。 (または 'atan2f'ですが、代わりに' 'を含める必要があります) –