web-dev-qa-db-ja.com

std :: transform()およびtoupper()、一致する関数なし

私はこの質問からコードを試しました C++ std :: transform()and toupper()..why this failed?

#include <iostream>
#include <algorithm>

int main() {
  std::string s="hello";
  std::string out;
  std::transform(s.begin(), s.end(), std::back_inserter(out), std::toupper);
  std::cout << "hello in upper case: " << out << std::endl;
}

理論的には、Josuttisの本の例の1つとして機能するはずですが、コンパイルされません http://ideone.com/aYnfv

GCCが文句を言った理由:

no matching function for call to ‘transform(
    __gnu_cxx::__normal_iterator<char*, std::basic_string
        <char, std::char_traits<char>, std::allocator<char> > >, 
    __gnu_cxx::__normal_iterator<char*, std::basic_string
        <char, std::char_traits<char>, std::allocator<char> > >, 
    std::back_insert_iterator<std::basic_string
        <char, std::char_traits<char>, std::allocator<char> > >,
    <unresolved overloaded function type>)’

ここに何かが足りませんか? GCC関連の問題ですか?

56
Stack Overeem

::toupperの代わりにstd::toupperを使用してください。つまり、toupper名前空間で定義されているものではなく、グローバル名前空間で定義されているstdです。

std::transform(s.begin(), s.end(), std::back_inserter(out), ::toupper);

その動作: http://ideone.com/XURh7

コードが機能しない理由:名前空間toupperに別のオーバーロード関数stdがあり、名前を解決するときに問題を引き起こしています。これは、コンパイラが参照しているオーバーロードを決定できないためです。 、単にstd::toupperを渡すとき。これが、コンパイラがエラーメッセージでunresolved overloaded function typeと言っている理由です。これは、オーバーロードの存在を示しています。

そのため、コンパイラが正しいオーバーロードを解決できるようにするには、std::toupperをキャストする必要があります。

(int (*)(int))std::toupper

つまり、次のように機能します。

//see the last argument, how it is casted to appropriate type
std::transform(s.begin(), s.end(), std::back_inserter(out),(int (*)(int))std::toupper);

自分でチェックしてください: http://ideone.com/8A6iV

69
Nawaz