Closed3

std::transform で怒られる

log5log5

std::transform で怒られる

あれ、なんで no matching function になるんやろ...

参考にしたサイト
https://programming-place.net/ppp/contents/cpp/rev_res/string000.html

試したこと

OKだった書き方
https://paiza.io/projects/bRXM2Bj3VInTAyzzgh5zNA?language=cpp

#include <bits/stdc++.h>
int main ()
{
    std::string s("aB3Cde_fG");

    std::transform (s.begin(), s.end(), s.begin(), toupper);
    std::cout << s << std::endl;
    std::transform (s.begin(), s.end(), s.begin(), tolower);
    std::cout << s << std::endl;

}

AB3CDE_FG
ab3cde_fg

ダメだった書き方
https://paiza.io/projects/tHYGfgkiH7EoR6UUM7bENQ?language=cpp

#include <bits/stdc++.h>
using namespace std;

int main ()
{
    string s("aB3Cde_fG");

    transform (s.begin(), s.end(), s.begin(), toupper);
    cout << s << endl;
    transform (s.begin(), s.end(), s.begin(), tolower);
    cout << s << endl;

}
Main.cpp:8:5: error: no matching function for call to 'transform'
    transform (s.begin(), s.end(), s.begin(), toupper);
    ^~~~~~~~~
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/stl_algo.h:4326:5: note: candidate template ignored: couldn't infer template argument '_UnaryOperation'
    transform(_InputIterator __first, _InputIterator __last,
    ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/stl_algo.h:4363:5: note: candidate function template not viable: requires 5 arguments, but 4 were provided
    transform(_InputIterator1 __first1, _InputIterator1 __last1,
    ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/pstl/glue_algorithm_defs.h:156:1: note: candidate function template not viable: requires 5 arguments, but 4 were provided
transform(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __result,
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/pstl/glue_algorithm_defs.h:162:1: note: candidate function template not viable: requires 6 arguments, but 4 were provided
transform(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2,
^
Main.cpp:10:5: error: no matching function for call to 'transform'
    transform (s.begin(), s.end(), s.begin(), tolower);
    ^~~~~~~~~
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/stl_algo.h:4326:5: note: candidate template ignored: couldn't infer template argument '_UnaryOperation'
    transform(_InputIterator __first, _InputIterator __last,
    ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/stl_algo.h:4363:5: note: candidate function template not viable: requires 5 arguments, but 4 were provided
    transform(_InputIterator1 __first1, _InputIterator1 __last1,
    ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/pstl/glue_algorithm_defs.h:156:1: note: candidate function template not viable: requires 5 arguments, but 4 were provided
transform(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __result,
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/pstl/glue_algorithm_defs.h:162:1: note: candidate function template not viable: requires 6 arguments, but 4 were provided
transform(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2,
^
2 errors generated.

candidate template ignored: couldn't infer template argument '_UnaryOperation'
が原因だとは思うけど、「そうか、推論できなかったんだね...」から先に進むにはどうすればいいのだろうか...

結局、using namespace std; を書いていると std::transform が使えなくなるってこと?
(そんな訳はないと思うんだけど...)

lewisacidlewisacid

これは using namespace std; によって std 名前空間内の std::touppertoupper として認識されているためだと思います。
C header の toupper は通常の関数ですが、C++ header の std::toupper は関数テンプレートとなっています。関数テンプレートは型を明示的に指定しないと型推論できないことが、本コードがエラーとなる直接の原因となっています。

意図した通りC header の toupper を呼ぶには、たとえば ::toupper と指定する方法があります。
https://wandbox.org/permlink/A3mf7zD0ZEO5zUyg

log5log5

なるほど、同名のシンボルが C++ header にもあったのですね!
教えていただき、ありがとうございます 🙏

このスクラップは2022/06/13にクローズされました