Да я могу и текст ошибки написать, мне не сложно.
A>Здравствуйте, DrMom, Вы писали:
DM>>//убираю коментарий и получаю ошибку. DM>>// eq(ref1, ref1);
A>это шутка такая -- "В чем ошибка?" A>текст ошибки сюда напиши, а еще лучше F1 нажми
c:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\include\functional(110) : error C2784: 'bool std::operator ==(const std::basic_string<_Elem,_Traits,_Alloc> &,const _Elem *)' : could not deduce template argument for 'const std::basic_string<_Elem,_Traits,_Alloc> &' from 'const RefS'
c:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\include\string(90) : see declaration of 'std::operator =='
c:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\include\functional(109) : while compiling class template member function 'bool std::equal_to<_Ty>::operator ()(const _Ty &,const _Ty &) const'
with
[
_Ty=RefS
]
..\..\PerformanceTest\main.cc(25) : see reference to class template instantiation 'std::equal_to<_Ty>' being compiled
with
[
_Ty=RefS
]
c:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\include\functional(110) : error C2784: 'bool std::operator ==(const _Elem *,const std::basic_string<_Elem,_Traits,_Alloc> &)' : could not deduce template argument for 'const _Elem *' from 'const RefS'
c:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\include\string(80) : see declaration of 'std::operator =='
c:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\include\functional(110) : error C2784: 'bool std::operator ==(const std::basic_string<_Elem,_Traits,_Alloc> &,const std::basic_string<_Elem,_Traits,_Alloc> &)' : could not deduce template argument for 'const std::basic_string<_Elem,_Traits,_Alloc> &' from 'const RefS'
c:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\include\string(70) : see declaration of 'std::operator =='
c:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\include\functional(110) : error C2784: 'bool std::operator ==(const std::istreambuf_iterator<_Elem,_Traits> &,const std::istreambuf_iterator<_Elem,_Traits> &)' : could not deduce template argument for 'const std::istreambuf_iterator<_Elem,_Traits> &' from 'const RefS'
c:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\include\streambuf(548) : see declaration of 'std::operator =='
c:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\include\functional(110) : error C2784: 'bool std::operator ==(const std::allocator<_Ty> &,const std::allocator<_Other> &) throw()' : could not deduce template argument for 'const std::allocator<_Ty> &' from 'const RefS'
c:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\include\xmemory(173) : see declaration of 'std::operator =='
c:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\include\functional(110) : error C2784: 'bool std::operator ==(const std::reverse_iterator<_RanIt> &,const std::reverse_iterator<_RanIt2> &)' : could not deduce template argument for 'const std::reverse_iterator<_RanIt> &' from 'const RefS'
c:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\include\xutility(2246) : see declaration of 'std::operator =='
c:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\include\functional(110) : error C2784: 'bool std::operator ==(const std::_Revranit<_RanIt,_Base> &,const std::_Revranit<_RanIt2,_Base2> &)' : could not deduce template argument for 'const std::_Revranit<_RanIt,_Base> &' from 'const RefS'
c:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\include\xutility(2050) : see declaration of 'std::operator =='
c:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\include\functional(110) : error C2784: 'bool std::operator ==(const std::pair<_Ty1,_Ty2> &,const std::pair<_Ty1,_Ty2> &)' : could not deduce template argument for 'const std::pair<_Ty1,_Ty2> &' from 'const RefS'
c:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\include\utility(83) : see declaration of 'std::operator =='
c:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\include\functional(110) : error C2676: binary '==' : 'const RefS' does not define this operator or a conversion to a type acceptable to the predefined operator
DM>bool operator==(const RefT& a, const RefT& b)
DM>{
DM> return a==b;
DM>}
DM>
вот этот операто просто не виден в глобальном пространстве имен... RefS это boost::reference wrapper из boost -- вот там и происходит поиск этого оператора...
ЗЫ: ну и понятное дело написан он у тя криво (и то что это скомпилится, если перенести), саапсем не значит что будет работать -- он у тя вызывает сам себя
Здравствуйте, zaufi, Вы писали:
Z>вот этот операто просто не виден в глобальном пространстве имен... RefS это boost::reference wrapper из boost -- вот там и происходит поиск этого оператора...
Здравствуйте, zaufi, Вы писали:
Z>Здравствуйте, DrMom, Вы писали:
DM>>
DM>>bool operator==(const RefT& a, const RefT& b)
DM>>{
DM>> return a==b;
DM>>}
DM>>
Z>вот этот операто просто не виден в глобальном пространстве имен... RefS это boost::reference wrapper из boost -- вот там и происходит поиск этого оператора...
Этого не понял. Можно поподробнее? Z>ЗЫ: ну и понятное дело написан он у тя криво (и то что это скомпилится, если перенести), саапсем не значит что будет работать -- он у тя вызывает сам себя
Здравствуйте, uzhas, Вы писали:
U>Здравствуйте, zaufi, Вы писали:
Z>>вот этот операто просто не виден в глобальном пространстве имен... RefS это boost::reference wrapper из boost -- вот там и происходит поиск этого оператора...
U>пытаюсь понять как же оно там работает U>пример 1 (компилируется): http://liveworkspace.org/code/1PSZtL$32 U>пример 2 (не компилируется): http://liveworkspace.org/code/1PSZtL$33 U>почему второй пример не собирается? ведь я воспроизвел реализацию std::equal_to в своем MyStd::MyEqual
Спасибо за корректировки.
ЗЫ Надо ссылочки прикопать. Удобно.
для начала пришлось обратиться к классикам: "C++ Templates: The Complete Guide" by David Vandevoorde, Nicolai M. Josuttis.
при парсе шаблонов, на первом этапе производится обычный поиск функций не зависящих от шаблонных параметров, а также, по возможности ADL для оных.
зависимые же функции ищутся подобным образом, затем составляется их список и запоминается до момента инстанциирования. в точке инстанциирования выполняется поиск для qualified имен с подставленными фактическими параметрами, и выполняется ADL для nonqualified имен (наколлекченых на первой фазе).
чтобы избавиться от лишних зависимостей (boost) я минимизировал пример до вот такого:
#include <functional>
#ifdef BEFORE
namespace zzz {
struct test {};
#ifdef INSIDE_NS
inline bool operator==(const test& a, const test& b)
{
return false;
}
#endif// INSIDE_NS
} // namespace zzz#ifdef OUTSIDE_NS
inline bool operator==(const zzz::test& a, const zzz::test& b)
{
return false;
}
#endif// OUTSIDE_NS#endif// BEFOREnamespace my {
template <class _Tp>
struct MyEqual : public std::binary_function<_Tp, _Tp, bool>
{
bool operator()(const _Tp& __x, const _Tp& __y) const
{
return __x == __y;
}
};
} // namespace my#ifdef AFTER
namespace zzz {
struct test {};
#ifdef INSIDE_NS
inline bool operator==(const test& a, const test& b)
{
return false;
}
#endif// INSIDE_NS
} // namespace zzz#ifdef OUTSIDE_NS
inline bool operator==(const zzz::test& a, const zzz::test& b)
{
return false;
}
#endif// OUTSIDE_NS#endif// AFTERint main()
{
zzz::test t;
{
my::MyEqual<zzz::test> eq;
eq(t, t);
}
{
std::equal_to<zzz::test> eq;
eq(t, t);
}
return 0;
}
дефайнами при компиляции рулится следующее:
BEFORE/AFTER -- определять тестовую структурку test в пространстве имен zzz ДО/ПОСЛЕ определения MyEqual (в пространстве имен my)
INSIDE_NS/OUTSIDE_NS -- определять operator== для zzz::test внутри/снаружи zzz
gcc 4.7.2 каким-то образом ухитрился скомпилячить все во всех случаях успешно -- вот этого я не понимаю... может надо багзилу ихнюю пошерстить...
zaufi@gentop /work/tests $ clang++ -DBEFORE -DINSIDE_NS -o refstr refstr.cc
zaufi@gentop /work/tests $ clang++ -DBEFORE -DOUTSIDE_NS -o refstr refstr.cc
In file included from refstr.cc:1:
In file included from /usr/lib/gcc/x86_64-pc-linux-gnu/4.7.2/include/g++-v4/functional:49:
/usr/lib/gcc/x86_64-pc-linux-gnu/4.7.2/include/g++-v4/bits/stl_function.h:210:20: error: call to function 'operator==' that is neither visible in the
template definition nor found by argument-dependent lookup
{ return __x == __y; }
^
refstr.cc:66:11: note: in instantiation of member function 'std::equal_to<zzz::test>::operator()' requested here
eq(t, t);
^
refstr.cc:19:13: note: 'operator==' should be declared prior to the call site or in namespace 'zzz'
inline bool operator==(const zzz::test& a, const zzz::test& b)
^
1 error generated.
zaufi@gentop /work/tests $ clang++ -DAFTER -DINSIDE_NS -o refstr refstr.cc
zaufi@gentop /work/tests $ clang++ -DAFTER -DOUTSIDE_NS -o refstr refstr.cc
refstr.cc:33:20: error: call to function 'operator==' that is neither visible in the template definition nor found by argument-dependent lookup
return __x == __y;
^
refstr.cc:62:11: note: in instantiation of member function 'my::MyEqual<zzz::test>::operator()' requested here
eq(t, t);
^
refstr.cc:50:13: note: 'operator==' should be declared prior to the call site or in namespace 'zzz'
inline bool operator==(const zzz::test& a, const zzz::test& b)
^
In file included from refstr.cc:1:
In file included from /usr/lib/gcc/x86_64-pc-linux-gnu/4.7.2/include/g++-v4/functional:49:
/usr/lib/gcc/x86_64-pc-linux-gnu/4.7.2/include/g++-v4/bits/stl_function.h:210:20: error: call to function 'operator==' that is neither visible in the
template definition nor found by argument-dependent lookup
{ return __x == __y; }
^
refstr.cc:66:11: note: in instantiation of member function 'std::equal_to<zzz::test>::operator()' requested here
eq(t, t);
^
refstr.cc:50:13: note: 'operator==' should be declared prior to the call site or in namespace 'zzz'
inline bool operator==(const zzz::test& a, const zzz::test& b)
^
2 errors generated.
clang 3.2 повел себя как и положенно(?) по книжке: operator== это очевидно зависимое имя, значит на втором этапе выполняется только ADL при поиске.
соответственно без разницы где находится определение zzz::test, до или после, определения my::MyEqual/std::equal_to, главное чтобы определение operator== для zzz::test находилось внутри пространства имен zzz. Либо, operator== может находится вне zzz, но он должен быть виден _до_ определения шаблона компаратора (о чем недвусмыленно пишет clang при компиляции с -DBEFORE -DOUTSIDE_NS: ошибка, естественно, только у std::equal_to, т.к. от за#includeн в начале файла
вот теперь думаю кто из них прав: gcc или clang... clang вроде все прально делает, но не оставляет мысль что это таки в нем какаянить бага (ибо молод еще)...
с другой стороны, gcc, по моим внутренним ощущениям должен быть менее глючным в поддержке С++03, но то что он все удачно собрал во всех вариантах, хотя казалось бы не должен, наводит на мысль что либо разработчики знают что-то чего я не допонимаю (вероятность чего конечно же высока), либо, что тоже известно, gcc сам "не без греха" (его базгилла также полна багов, правда как мне кажется, таких концептуальных как у clang у него поменьше будет)