6

渡された関数が適切な型に暗黙的にキャストされるように、反復可能関数と関数を受け入れるテンプレート化された関数を作成しようとしていますstd::function(したがって、完全な関数とラムダの両方で使用できます)。

コードは次のとおりです。

#include <iostream>
#include <vector>
#include <algorithm>
#include <typeinfo>


template<typename T>
void bar(const T & base, std::function<bool(int)> f) // works
//void bar(const T & base, std::function<bool(typename T::iterator::value_type)> f) // fails to compile
{
    std::cout << ((typeid(std::function<bool(int)>) == typeid(std::function<bool(typename T::iterator::value_type)>))?"identical":"distinct") << std::endl;
}

bool filter(int x) { return x%2==0; }

int main() { bar(std::vector<int> {0, 1}, filter); }

これでコンパイルするとg++-4.7 -std=c++11 -o itest itest.cpp、 が生成されidenticalます。

10 行目のコメントを外し、9 行目のコメントを外して上記のようにコンパイルすると、代わりにコンパイルが失敗します。

g++-4.7 -std=c++11 -Wall -Werror  -o itest itest.cpp
itest.cpp: In function 'int main()':
itest.cpp:16:53: error: no matching function for call to 'bar(std::vector<int>, bool (&)(int))'
itest.cpp:16:53: note: candidate is:
itest.cpp:9:10: note: template<class T> void bar(const T&, std::function<bool(typename T::iterator::value_type)>)
itest.cpp:9:10: note:   template argument deduction/substitution failed:
itest.cpp:16:53: note:   mismatched types 'std::function<bool(typename T::iterator::value_type)>' and 'bool (*)(int)'

変更されていないバージョンは (適切なオプションを設定して) Xcode で成功することに注意してください。私は何か間違ったことをしていますか、それともこれは g++ の既知のバグですか?

4

2 に答える 2

2

ポインタ関数には2番目のオーバーロードが必要です-それからコンパイルされます。動作しない暗黙のキャストstd::function

void bar(const T & base, bool(*f)(typename T::value_type)){
    std::cout << "ptr func\n";
}

ecatmur(いくつかのT、関数signutreのタイプが一致しない)によって記述された問題の回避策:他のTをidentitystructでラップできます。これは次のように定義されます。

template<class T> struct identity{ typedef T type; };

その場合、コンパイラは型の推定のためにこれらのTを無視します。

于 2012-09-03T18:33:58.243 に答える