Оператор << уже реализован, но компилятор жалуется, что это не так - PullRequest
0 голосов
/ 04 февраля 2020

Я новичок ie с C ++, а также с Boost Tests. Я использую Visual C ++ на Windows 7.

Я реализовал эти операторы в том же исходном файле теста, где тесты:

std::ostream& operator<<(std::ostream& os, const std::tuple<utils::angle, utils::angle>& tuple)
{
    os << std::get<0>(tuple) << ", " << std::get<1>(tuple) << std::endl;

    return os;
}

bool operator ==(std::tuple<utils::angle, utils::angle> const &left,
    std::tuple<utils::angle, utils::angle> const &right)
{
    return (std::get<0>(left) == std::get<0>(right)) &&
        (std::get<1>(left) == std::get<1>(right));
}

Структура utils::angle также имеет реализовал оба оператора в другом файле с именем Utils.cpp:

bool utils::operator ==(utils::angle const &left, utils::angle const &right)
{
    return(
        left.secs == right.secs
        && left.min == right.min
        && left.degree == right.degree);
}

std::ostream& utils::operator<<(std::ostream& os, const utils::angle& ag)
{
    os << ag.degree << "º " << ag.min << "' " << ag.secs << "\"" << std::endl;

    return os;
}

И тест, который не может быть скомпилирован, выглядит так:

BOOST_AUTO_TEST_CASE(EquatorialToHorizonCoordinate_1)
{
    int latitude = 52;
    char orientation = 'N';
    utils::astTime hourAngle = { 5, 51, 44 };
    utils::angle declination = { 23, 13, 10 };

    utils::angle altitude = { 19, 20, 3.64 };
    utils::angle azimuth = { 283, 16, 15.70 };
    std::tuple<utils::angle, utils::angle> tuple = 
        std::make_tuple(altitude, azimuth);

    BOOST_REQUIRE_EQUAL(tuple, coord_instance.EquatorialToHorizonCoordinate(latitude, orientation, hourAngle, declination));
}

Если я прокомментирую приведенный выше тест и operator<< и operator== для std::tuple<utils::angle, utils::angle> он компилируется и запускается без проблем.

Когда я его компилирую, я получаю эту ошибку на экране вывода:

error C2338: Type has to implement operator<< to be printable note:
see reference to function template instantiation 'std::ostream
&boost::test_tools::tt_detail::impl::boost_test_print_type<R>(std::ostream
&,const T &)' being compiled
        with
        [
            R=std::tuple<utils::angle,utils::angle>,
            T=std::tuple<utils::angle,utils::angle>
        ]

И на экране ошибок Visual Studio я получаю эти две ошибки:

C2338 Type has to implement operator<< to be printable<br/>
C2679 binary '<<': no operator found which takes a right-hand operand
of type 'const T' (or there is no acceptable conversion)

Есть что-то, чего я не понимаю, потому что я думаю, что реализовал этот оператор.

Что я делаю не так?

ОБНОВЛЕНИЕ:

Если я удаляю реализацию операторов, я получаю ту же ошибку.

Я обнаружил эти "ошибки" в окне вывода:

note: or       'std::ostream &utils::operator <<(std::ostream &,const utils::astTime &)' [found using argument-dependent lookup]
note: or       'std::ostream &utils::operator <<(std::ostream &,const utils::dateTime &)' [found using argument-dependent lookup]
note: or       'std::ostream &utils::operator <<(std::ostream &,const utils::angle &)' [found using argument-dependent lookup]

Это что-то про ADL.

Все содержимое окна вывода здесь:

1>------ Rebuild All started: Project: AstroLibrary, Configuration: Debug Win32 ------
1>AstroTime.cpp
1>d:\sources\repos\myProject\v2\astrolibraries\astrotime\astrotime.cpp(142): warning C4244: 'return': conversion from 'double' to 'unsigned int', possible loss of data
1>d:\sources\repos\myProject\v2\astrolibraries\astrotime\astrotime.cpp(181): warning C4838: conversion from 'unsigned int' to 'double' requires a narrowing conversion
1>d:\sources\repos\myProject\v2\astrolibraries\astrotime\astrotime.cpp(181): warning C4838: conversion from 'unsigned int' to 'int' requires a narrowing conversion
1>d:\sources\repos\myProject\v2\astrolibraries\astrotime\astrotime.cpp(386): warning C4838: conversion from 'int' to 'double' requires a narrowing conversion
1>CoordinateSystems.cpp
1>Utils.cpp
1>Generating Code...
1>AstroTime.vcxproj -> D:\sources\Repos\myProject\v2\AstroLibraries\Debug\AstroLibrary.lib
1>Done building project "AstroTime.vcxproj".
2>------ Rebuild All started: Project: AstroLibraryTest, Configuration: Debug Win32 ------
2>AstroTimeTest.cpp
2>d:\sources\repos\myProject\v2\astrolibraries\test\astrotimetest\astrotimetest.cpp(77): warning C4838: conversion from 'unsigned int' to 'int' requires a narrowing conversion
2>d:\sources\repos\myProject\v2\astrolibraries\test\astrotimetest\astrotimetest.cpp(85): warning C4838: conversion from 'unsigned int' to 'int' requires a narrowing conversion
2>d:\sources\repos\myProject\v2\astrolibraries\test\astrotimetest\astrotimetest.cpp(93): warning C4838: conversion from 'unsigned int' to 'int' requires a narrowing conversion
2>d:\sources\repos\myProject\v2\astrolibraries\test\astrotimetest\astrotimetest.cpp(276): warning C4244: 'argument': conversion from 'double' to 'int', possible loss of data
2>d:\sources\repos\myProject\v2\astrolibraries\test\astrotimetest\astrotimetest.cpp(286): warning C4244: 'argument': conversion from 'double' to 'int', possible loss of data
2>CoordinateSystemsTest.cpp
2>d:\main\vcpkg-master\installed\x86-windows\include\boost\test\tools\detail\print_helper.hpp(53): error C2338: Type has to implement operator<< to be printable
2>d:\main\vcpkg-master\installed\x86-windows\include\boost\test\tools\detail\print_helper.hpp(62): note: see reference to function template instantiation 'std::ostream &boost::test_tools::tt_detail::impl::boost_test_print_type<R>(std::ostream &,const T &)' being compiled
2>        with
2>        [
2>            R=std::tuple<utils::angle,utils::angle>,
2>            T=std::tuple<utils::angle,utils::angle>
2>        ]
2>d:\main\vcpkg-master\installed\x86-windows\include\boost\test\tools\detail\print_helper.hpp(91): note: see reference to function template instantiation 'std::ostream &boost::test_tools::tt_detail::impl::boost_test_print_type_impl::operator ()<T>(std::ostream &,const R &) const' being compiled
2>        with
2>        [
2>            T=std::tuple<utils::angle,utils::angle>,
2>            R=std::tuple<utils::angle,utils::angle>
2>        ]
2>d:\main\vcpkg-master\installed\x86-windows\include\boost\test\tools\detail\print_helper.hpp(84): note: while compiling class template member function 'void boost::test_tools::tt_detail::print_log_value<T>::operator ()(std::ostream &,const T &)'
2>        with
2>        [
2>            T=std::tuple<utils::angle,utils::angle>
2>        ]
2>d:\main\vcpkg-master\installed\x86-windows\include\boost\test\tools\detail\print_helper.hpp(220): note: see reference to function template instantiation 'void boost::test_tools::tt_detail::print_log_value<T>::operator ()(std::ostream &,const T &)' being compiled
2>        with
2>        [
2>            T=std::tuple<utils::angle,utils::angle>
2>        ]
2>d:\main\vcpkg-master\installed\x86-windows\include\boost\test\tools\detail\print_helper.hpp(220): note: see reference to class template instantiation 'boost::test_tools::tt_detail::print_log_value<T>' being compiled
2>        with
2>        [
2>            T=std::tuple<utils::angle,utils::angle>
2>        ]
2>d:\main\vcpkg-master\installed\x86-windows\include\boost\test\utils\lazy_ostream.hpp(67): note: see reference to function template instantiation 'std::ostream &boost::test_tools::tt_detail::operator <<<Arg0>(std::ostream &,const boost::test_tools::tt_detail::print_helper_t<Arg0> &)' being compiled
2>        with
2>        [
2>            Arg0=std::tuple<utils::angle,utils::angle>
2>        ]
2>d:\main\vcpkg-master\installed\x86-windows\include\boost\test\utils\lazy_ostream.hpp(66): note: while compiling class template member function 'std::ostream &boost::unit_test::lazy_ostream_impl<boost::unit_test::lazy_ostream,boost::test_tools::tt_detail::print_helper_t<Arg0>,const T &>::operator ()(std::ostream &) const'
2>        with
2>        [
2>            Arg0=std::tuple<utils::angle,utils::angle>,
2>            T=boost::test_tools::tt_detail::print_helper_t<std::tuple<utils::angle,utils::angle>>
2>        ]
2>d:\main\vcpkg-master\installed\x86-windows\include\boost\test\tools\old\impl.hpp(92): note: see reference to class template instantiation 'boost::unit_test::lazy_ostream_impl<boost::unit_test::lazy_ostream,boost::test_tools::tt_detail::print_helper_t<Arg0>,const T &>' being compiled
2>        with
2>        [
2>            Arg0=std::tuple<utils::angle,utils::angle>,
2>            T=boost::test_tools::tt_detail::print_helper_t<std::tuple<utils::angle,utils::angle>>
2>        ]
2>d:\sources\repos\myProject\v2\astrolibraries\test\astrotimetest\coordinatesystemstest.cpp(96): note: see reference to function template instantiation 'bool boost::test_tools::tt_detail::check_frwd<boost::test_tools::tt_detail::equal_impl_frwd,std::tuple<utils::angle,utils::angle>,std::tuple<utils::angle,utils::angle>>(Pred,const boost::unit_test::lazy_ostream &,boost::unit_test::const_string,size_t,boost::test_tools::tt_detail::tool_level,boost::test_tools::tt_detail::check_type,const Arg0 &,const char *,const Arg1 &,const char *)' being compiled
2>        with
2>        [
2>            Pred=boost::test_tools::tt_detail::equal_impl_frwd,
2>            Arg0=std::tuple<utils::angle,utils::angle>,
2>            Arg1=std::tuple<utils::angle,utils::angle>
2>        ]
2>d:\main\vcpkg-master\installed\x86-windows\include\boost\test\tools\detail\print_helper.hpp(55): error C2679: binary '<<': no operator found which takes a right-hand operand of type 'const T' (or there is no acceptable conversion)
2>        with
2>        [
2>            T=std::tuple<utils::angle,utils::angle>
2>        ]
2>c:\program files (x86)\microsoft visual studio\2017\enterprise\vc\tools\msvc\14.16.27023\include\ostream(508): note: could be 'std::basic_ostream<char,std::char_traits<char>> &std::basic_ostream<char,std::char_traits<char>>::operator <<(std::basic_streambuf<char,std::char_traits<char>> *)'
2>c:\program files (x86)\microsoft visual studio\2017\enterprise\vc\tools\msvc\14.16.27023\include\ostream(480): note: or       'std::basic_ostream<char,std::char_traits<char>> &std::basic_ostream<char,std::char_traits<char>>::operator <<(const void *)'
2>c:\program files (x86)\microsoft visual studio\2017\enterprise\vc\tools\msvc\14.16.27023\include\ostream(460): note: or       'std::basic_ostream<char,std::char_traits<char>> &std::basic_ostream<char,std::char_traits<char>>::operator <<(long double)'
2>c:\program files (x86)\microsoft visual studio\2017\enterprise\vc\tools\msvc\14.16.27023\include\ostream(440): note: or       'std::basic_ostream<char,std::char_traits<char>> &std::basic_ostream<char,std::char_traits<char>>::operator <<(double)'
2>c:\program files (x86)\microsoft visual studio\2017\enterprise\vc\tools\msvc\14.16.27023\include\ostream(420): note: or       'std::basic_ostream<char,std::char_traits<char>> &std::basic_ostream<char,std::char_traits<char>>::operator <<(float)'
2>c:\program files (x86)\microsoft visual studio\2017\enterprise\vc\tools\msvc\14.16.27023\include\ostream(400): note: or       'std::basic_ostream<char,std::char_traits<char>> &std::basic_ostream<char,std::char_traits<char>>::operator <<(unsigned __int64)'
2>c:\program files (x86)\microsoft visual studio\2017\enterprise\vc\tools\msvc\14.16.27023\include\ostream(380): note: or       'std::basic_ostream<char,std::char_traits<char>> &std::basic_ostream<char,std::char_traits<char>>::operator <<(__int64)'
2>c:\program files (x86)\microsoft visual studio\2017\enterprise\vc\tools\msvc\14.16.27023\include\ostream(360): note: or       'std::basic_ostream<char,std::char_traits<char>> &std::basic_ostream<char,std::char_traits<char>>::operator <<(unsigned long)'
2>c:\program files (x86)\microsoft visual studio\2017\enterprise\vc\tools\msvc\14.16.27023\include\ostream(340): note: or       'std::basic_ostream<char,std::char_traits<char>> &std::basic_ostream<char,std::char_traits<char>>::operator <<(long)'
2>c:\program files (x86)\microsoft visual studio\2017\enterprise\vc\tools\msvc\14.16.27023\include\ostream(320): note: or       'std::basic_ostream<char,std::char_traits<char>> &std::basic_ostream<char,std::char_traits<char>>::operator <<(unsigned int)'
2>c:\program files (x86)\microsoft visual studio\2017\enterprise\vc\tools\msvc\14.16.27023\include\ostream(295): note: or       'std::basic_ostream<char,std::char_traits<char>> &std::basic_ostream<char,std::char_traits<char>>::operator <<(int)'
2>c:\program files (x86)\microsoft visual studio\2017\enterprise\vc\tools\msvc\14.16.27023\include\ostream(275): note: or       'std::basic_ostream<char,std::char_traits<char>> &std::basic_ostream<char,std::char_traits<char>>::operator <<(unsigned short)'
2>c:\program files (x86)\microsoft visual studio\2017\enterprise\vc\tools\msvc\14.16.27023\include\ostream(241): note: or       'std::basic_ostream<char,std::char_traits<char>> &std::basic_ostream<char,std::char_traits<char>>::operator <<(short)'
2>c:\program files (x86)\microsoft visual studio\2017\enterprise\vc\tools\msvc\14.16.27023\include\ostream(221): note: or       'std::basic_ostream<char,std::char_traits<char>> &std::basic_ostream<char,std::char_traits<char>>::operator <<(bool)'
2>c:\program files (x86)\microsoft visual studio\2017\enterprise\vc\tools\msvc\14.16.27023\include\ostream(215): note: or       'std::basic_ostream<char,std::char_traits<char>> &std::basic_ostream<char,std::char_traits<char>>::operator <<(std::ios_base &(__cdecl *)(std::ios_base &))'
2>c:\program files (x86)\microsoft visual studio\2017\enterprise\vc\tools\msvc\14.16.27023\include\ostream(209): note: or       'std::basic_ostream<char,std::char_traits<char>> &std::basic_ostream<char,std::char_traits<char>>::operator <<(std::basic_ios<char,std::char_traits<char>> &(__cdecl *)(std::basic_ios<char,std::char_traits<char>> &))'
2>c:\program files (x86)\microsoft visual studio\2017\enterprise\vc\tools\msvc\14.16.27023\include\ostream(204): note: or       'std::basic_ostream<char,std::char_traits<char>> &std::basic_ostream<char,std::char_traits<char>>::operator <<(std::basic_ostream<char,std::char_traits<char>> &(__cdecl *)(std::basic_ostream<char,std::char_traits<char>> &))'
2>d:\sources\repos\myProject\v2\astrolibraries\astrotime\utils.h(14): note: or       'std::ostream &utils::operator <<(std::ostream &,const utils::astTime &)' [found using argument-dependent lookup]
2>d:\sources\repos\myProject\v2\astrolibraries\astrotime\utils.h(26): note: or       'std::ostream &utils::operator <<(std::ostream &,const utils::dateTime &)' [found using argument-dependent lookup]
2>d:\sources\repos\myProject\v2\astrolibraries\astrotime\utils.h(36): note: or       'std::ostream &utils::operator <<(std::ostream &,const utils::angle &)' [found using argument-dependent lookup]
2>c:\program files (x86)\microsoft visual studio\2017\enterprise\vc\tools\msvc\14.16.27023\include\ostream(702): note: or       'std::basic_ostream<char,std::char_traits<char>> &std::operator <<<char,std::char_traits<char>>(std::basic_ostream<char,std::char_traits<char>> &,const char *)'
2>c:\program files (x86)\microsoft visual studio\2017\enterprise\vc\tools\msvc\14.16.27023\include\ostream(749): note: or       'std::basic_ostream<char,std::char_traits<char>> &std::operator <<<char,std::char_traits<char>>(std::basic_ostream<char,std::char_traits<char>> &,char)'
2>c:\program files (x86)\microsoft visual studio\2017\enterprise\vc\tools\msvc\14.16.27023\include\ostream(787): note: or       'std::basic_ostream<char,std::char_traits<char>> &std::operator <<<std::char_traits<char>>(std::basic_ostream<char,std::char_traits<char>> &,const char *)'
2>c:\program files (x86)\microsoft visual studio\2017\enterprise\vc\tools\msvc\14.16.27023\include\ostream(834): note: or       'std::basic_ostream<char,std::char_traits<char>> &std::operator <<<std::char_traits<char>>(std::basic_ostream<char,std::char_traits<char>> &,char)'
2>c:\program files (x86)\microsoft visual studio\2017\enterprise\vc\tools\msvc\14.16.27023\include\ostream(960): note: or       'std::basic_ostream<char,std::char_traits<char>> &std::operator <<<std::char_traits<char>>(std::basic_ostream<char,std::char_traits<char>> &,const signed char *)'
2>c:\program files (x86)\microsoft visual studio\2017\enterprise\vc\tools\msvc\14.16.27023\include\ostream(967): note: or       'std::basic_ostream<char,std::char_traits<char>> &std::operator <<<std::char_traits<char>>(std::basic_ostream<char,std::char_traits<char>> &,signed char)'
2>c:\program files (x86)\microsoft visual studio\2017\enterprise\vc\tools\msvc\14.16.27023\include\ostream(974): note: or       'std::basic_ostream<char,std::char_traits<char>> &std::operator <<<std::char_traits<char>>(std::basic_ostream<char,std::char_traits<char>> &,const unsigned char *)'
2>c:\program files (x86)\microsoft visual studio\2017\enterprise\vc\tools\msvc\14.16.27023\include\ostream(981): note: or       'std::basic_ostream<char,std::char_traits<char>> &std::operator <<<std::char_traits<char>>(std::basic_ostream<char,std::char_traits<char>> &,unsigned char)'
2>c:\program files (x86)\microsoft visual studio\2017\enterprise\vc\tools\msvc\14.16.27023\include\ostream(1047): note: or       'std::basic_ostream<char,std::char_traits<char>> &std::operator <<<char,std::char_traits<char>>(std::basic_ostream<char,std::char_traits<char>> &,const std::error_code &)'
2>d:\main\vcpkg-master\installed\x86-windows\include\boost\test\tools\detail\print_helper.hpp(55): note: while trying to match the argument list '(std::ostream, const T)'
2>        with
2>        [
2>            T=std::tuple<utils::angle,utils::angle>
2>        ]
2>test_main.cpp
2>Generating Code...
2>Done building project "AstroTimeTest.vcxproj" -- FAILED.
========== Rebuild All: 1 succeeded, 1 failed, 0 skipped ==========

ОБНОВЛЕНИЕ 2 У меня есть этот другой тест на том же исходном тестовом файле:

BOOST_AUTO_TEST_CASE(DecimalDegreesToDegrees_1)
{
    double decDegrees = 182.524167;
    utils::angle degrees = { 182, 31, 27.0 };

    BOOST_REQUIRE_EQUAL(degrees, coord_instance.DecimalDegreesToDegrees(decDegrees));
}

Работает нормально: компилируется и запускается без ошибок.

UPDATE 3

Если я использую свою собственную структуру, utils::altazm, а я не использую std::tuple, это работает.

...