Update: using catch 1.9.7 solved this problem.
I am just getting started with using catch and have been unable to get even a simple test project to compile. I am using Visual Studio 2008 and have catch.hpp v1.10.0 (single file version).
I created a simple test project following the catch tutorial. main.cpp is the only file and the code consists of:
#define CATCH_CONFIG_MAIN
#include "catch.hpp"
TEST_CASE("test case 1")
{
REQUIRE(1==2);
}
I get the following errors when I compile:
c:\utilities\catch\catchtest\catchtest\catch.hpp(1333) : warning C4181: qualifier applied to reference type; ignored
c:\utilities\catch\catchtest\catchtest\catch.hpp(1838) : see reference to class template instantiation 'Catch::Internal::Evaluator<T1,T2,Op>' being compiled
with
[
T1=const int &,
T2=const int &,
Op=IsEqualTo
]
c:\utilities\catch\catchtest\catchtest\catch.hpp(1836) : while compiling class template member function 'void Catch::BinaryExpression<LhsT,Op,RhsT>::endExpression(void) const'
with
[
LhsT=const int &,
Op=IsEqualTo,
RhsT=const int &
]
c:\utilities\catch\catchtest\catchtest\main.cpp(8) : see reference to class template instantiation 'Catch::BinaryExpression<LhsT,Op,RhsT>' being compiled
with
[
LhsT=const int &,
Op=IsEqualTo,
RhsT=const int &
]
c:\utilities\catch\catchtest\catchtest\catch.hpp(1333) : error C2529: 'lhs' : reference to reference is illegal
c:\utilities\catch\catchtest\catchtest\catch.hpp(1333) : warning C4181: qualifier applied to reference type; ignored
c:\utilities\catch\catchtest\catchtest\catch.hpp(1333) : error C2529: 'rhs' : reference to reference is illegal
c:\utilities\catch\catchtest\catchtest\catch.hpp(1838) : error C2664: 'Catch::Internal::Evaluator<T1,T2,Op>::evaluate' : cannot convert parameter 1 from 'const int' to 'const int &(&)'
with
[
T1=const int &,
T2=const int &,
Op=IsEqualTo
]
c:\utilities\catch\catchtest\catchtest\catch.hpp(1839) : error C2228: left of '.endExpression' must have class/struct/union
Any assistance would be much appreciated. I haven't been able to find anything in the catch documentation or online and am eager to get started with it.
The latest master of Catch is for modern C++ compiler and the Visual Studio 2008 compiler is pretty old now. There's some switches you can use to downgrade some of the features:
https://github.com/philsquared/Catch/blob/master/docs/configuration.md
Try it with 'CATCH_CONFIG_NO_CPP11' defined before #include'ing catch.
For future reference: support for MSVC 9 was broken by this commit and reverting b6e7c9bd7a160c07c5de894292022687895c17a3 (done on top of it) and then this one is sufficient to fix the problem.
Related
Porting an application to Windows, I am now trying to compile it with VS2017 and am running into a host of problems. One of which is that a template wrapper I wrote to make a C++ member function available to be called from a C library (FUSE) doesn't work:
template <class T> class Callback {};
template <class T, class ...Arguments>
struct Callback<T(Arguments...)>
{
template <T(operations::*CALLBACK)(Arguments...)>
static T wrap(Arguments... parameters)
{
auto *instance = static_cast<operations*>(fuse_get_context()->private_data);
return (instance->*CALLBACK)(std::forward<Arguments>(parameters)...);
}
};
I am trying to set the callbacks like this in the constructor:
_operations.get_attr = Callback<std::remove_reference<decltype(*_high_level.getattr)>::type>::wrap<&operations::getattr>;
This is - I believe - valid code, but it doesn't comopile with some warnings and an error:
warning C4229: anachronism used: modifiers on data are ignored
error C2760: syntax error: unexpected token '__cdecl', expected 'expression'
note: see reference to function template instantiation 'T Callback<int (const char *,stat64_cygwin *)>::wrap<int operations::getattr(const char *,stat64_cygwin *)>(const char *,stat64_cygwin *)' being compiled
with
[
T=int
]
note: see reference to function template instantiation 'T Callback<int (const char *,stat64_cygwin *)>::wrap<int operations::getattr(const char *,stat64_cygwin *)>(const char *,stat64_cygwin *)' being compiled
with
[
T=int
]
error C2059: syntax error: '__cdecl'
The warning about anachronisms points to the line containing the template specifications for the wrap function. The error points to the line where the callback is actually invoked and returned, inside the wrap function.
It's very confusing, after reading somewhat I found that anachronisms are the sort-of attributes used in Windows APIs, which I don't use here, and I also don't have any __cdecl here. I have no idea how to proceed here.
Renaming CALLBACK to MEMFUNC worked. Apparantly, Windows defines CALLBACK to something unexpected, causing the code to be expanded in a way it doesn't compile.
Besides the fact that it's weird to just define random stuff like this (without prefixing it with WINDOWS_), it's unfortunate that the compiler generates errors which do not properly indicate that it originates in some #define, making it hard to debug.
i have Microsoft Visual Studio (MSVS) 2012 Pro and i have set warning level to a slightly elevated level of 4. when doing this i am getting warnings for some of the included header files from the boost library. the message is this:
C:\Users\****\boost/optional/optional.hpp(595): warning C4244: 'initializing' : conversion from 'T_DOUBLE' to 'float', possible loss of data
C:\Users\****\boost/optional/optional.hpp(430) : see reference to function template instantiation 'void boost::optional_detail::optional_base<T>::construct<double>(Expr &&,const void *)' being compiled
with
[
T=T_FLOAT,
Expr=T_DOUBLE
]
C:\Users\****\boost/optional/optional.hpp(430) : see reference to function template instantiation 'void boost::optional_detail::optional_base<T>::construct<double>(Expr &&,const void *)' being compiled
with
[
T=T_FLOAT,
Expr=T_DOUBLE
]
the code in the file leading to this warning is this (line 610 on most recent beta of boost 1.64.0.B2 still resembles it exactly - but i am not on the beta now):
#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
// Constructs using any expression implicitly convertible to the single argument
// of a one-argument T constructor.
// Converting constructions of optional<T> from optional<U> uses this function with
// 'Expr' being of type 'U' and relying on a converting constructor of T from U.
template<class Expr>
void construct ( Expr&& expr, void const* )
{
new (m_storage.address()) value_type(boost::forward<Expr>(expr)) ;
m_initialized = true ;
}
what is the reason (=learn to understand) for this warning and how to eliminate it in the boost header for me any anyone else? alternatively thinking: does it make sense to "fix" it in such a global way, or is there a deeper meaning pointing rather to somewhere else (either boost or application codes) to improve or fix those other codes?
You are probably passing a double literal into method that expects float. Something like foo(1.0) instead of foo(1.0f)
Consider this code snippet:
void Foo(std::string str1, std::string str2) {}
template<typename... Types>
void Bar()
{
Foo(Types{}...); // wont compile
}
Bar<std::string, std::string>();
What I want to do here is to default construct two std::string objects inside the Bar method and pass them to Foo. However my vain attempts (one of them being in the snippet) wont compile so I am wondering whether this is even possible.
I compiled with VC 2013, which throws compiler errors at me. As stated in the comments, other compilers can handle it. Can anyone tell whether the above snippet is standard conform?
It's a problem in the MSVC variadic template expansion process; when it unpacks the list of types it fails to recognise them as suitable for a constructor call. As a workaround, you can perform a type transformation to force the compiler to recognise them:
template<typename T> using identity_t = T; // NEW CODE
void Foo(int, int);
template<typename... Types>
void Bar()
{
Foo(identity_t<Types>{}...); // use identity type transformation
}
int main() {
Bar<int, int>();
}
I haven't managed to find an issue number yet.
This crashes the VC 2013 compiler for me. The errors seem to indicate that it has some problems parsing the code. So when the compiler crashes it must be a compiler bug.
1>main.cpp(23): error C2144: syntax error : 'std::string' should be preceded by ')'
1> main.cpp(28) : see reference to function template instantiation 'void Bar<std::string,std::string>(void)' being compiled
1>main.cpp(23): error C2660: 'Foo' : function does not take 0 arguments
1>main.cpp(23): error C2143: syntax error : missing ';' before '{'
1>main.cpp(23): error C2143: syntax error : missing ';' before ','
1>c1xx : fatal error C1063: INTERNAL COMPILER ERROR
1> Please choose the Technical Support command on the Visual C++
1> Help menu, or open the Technical Support help file for more information
1>cl : Command line warning D9028: minimal rebuild failure, reverting to normal build
1>
1>Build FAILED.
I'm trying to fill std::map with std::transform. Next code compiles without error:
std::set<std::wstring> in; // "in" is filled with data
std::map<std::wstring, unsigned> out;
std::transform(in.begin(), in.end()
, boost::counting_iterator<unsigned>(0)
, std::inserter(out, out.end())
, [] (std::wstring _str, unsigned _val) { return std::make_pair(_str, _val); }
);
But If I replace string
, [] (std::wstring _str, unsigned _val) { return std::make_pair(_str, _val); }
with
, std::make_pair<std::wstring, unsigned>
or
, std::ptr_fun(std::make_pair<std::wstring, unsigned>)
I get errors:
foo.cpp(327): error C2784: '_OutTy *std::transform(_InIt1,_InIt1,_InTy (&)[_InSize],_OutTy (&)[_OutSize],_Fn2)' : could not deduce template argument for '_InTy (&)[_InSize]' from 'boost::counting_iterator<Incrementable>'
with
[
Incrementable=unsigned int
]
C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\algorithm(1293) : see declaration of 'std::transform'
foo.cpp(327): error C2784: '_OutTy *std::transform(_InIt1,_InIt1,_InIt2,_OutTy (&)[_OutSize],_Fn2)' : could not deduce template argument for '_OutTy (&)[_OutSize]' from 'std::insert_iterator<_Container>'
with
[
_Container=std::map<std::wstring,unsigned int>
]
C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\algorithm(1279) : see declaration of 'std::transform'
foo.cpp(327): error C2784: '_OutIt std::transform(_InIt1,_InIt1,_InTy (&)[_InSize],_OutIt,_Fn2)' : could not deduce template argument for '_InTy (&)[_InSize]' from 'boost::counting_iterator<Incrementable>'
with
[
Incrementable=unsigned int
]
C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\algorithm(1267) : see declaration of 'std::transform'
foo.cpp(327): error C2914: 'std::transform' : cannot deduce template argument as function argument is ambiguous
and so on...
Please explain what is the problem is with compilation?
UPDATE: Thanks for answers. I realized, that it is MSVC2010 bug. By the way the line
&std::make_pair<const std::wstring&, const unsigned&>
causes the same error
This is a bug in the Visual C++ library implementation. The following program demonstrates the issue:
#include <utility>
int main()
{
&std::make_pair<int, int>;
};
This program yields the error:
error C2568: 'identifier' : unable to resolve function overload
In the C++ language specification, make_pair is not an overloaded function. The Visual C++ 2010 library implementation includes four overloads taking various combinations of lvalue and rvalue references.
While an implementation of the C++ Standard Library is allowed to add overloads for member functions, it isn't allowed to add overloads for nonmember functions, thus this is a bug.
The bug was reported and will be fixed in the next version of Visual C++. However, as STL notes in the resolution to that bug, you'll need to make the template arguments to std::make_pair lvalue references:
&std::make_pair<const std::wstring&, const unsigned&>
g++ 4.4.5 compiles it without errors. Seems to be a Visual Studio 10 defect.
I was using Boost 1.38, and I just upgraded to 1.39. Upgrading broke the following bit of code:
std::vector<std::wstring> consoleParser::loadStringsFromFile(const std::wstring &fileName)
{
std::vector<std::wstring> files;
std::wstring fileString(loadFileAsString(fileName));
boost::algorithm::split(files, fileString, boost::is_any_of(L"\r\n'\"")); //Error on this line
return files;
}
Any ideas on what's causing the failure? My compiler helpfully emits the following:
c:\boost\boost\utility\addressof.hpp(30) : error C2220: warning treated as error - no 'object' file generated
c:\boost\boost\utility\addressof.hpp(56) : see reference to class template instantiation 'boost::detail::addr_impl_ref<T>' being compiled
with
[
T=boost::algorithm::detail::token_finderF<boost::algorithm::detail::is_any_ofF<wchar_t>>
]
c:\boost\boost\function\function_template.hpp(600) : see reference to function template instantiation 'T *boost::addressof<FunctionObj>(T &)' being compiled
with
[
T=boost::algorithm::detail::token_finderF<boost::algorithm::detail::is_any_ofF<wchar_t>>,
FunctionObj=boost::algorithm::detail::token_finderF<boost::algorithm::detail::is_any_ofF<wchar_t>>
]
c:\boost\boost\function\function_template.hpp(491) : see reference to function template instantiation 'bool boost::detail::function::basic_vtable2<R,T0,T1>::assign_to<F>(FunctionObj,boost::detail::function::function_buffer &,boost::detail::function::function_obj_tag)' being compiled
with
[
R=boost::iterator_range<std::_String_iterator<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t>>>,
T0=std::_String_iterator<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t>>,
T1=std::_String_iterator<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t>>,
F=boost::algorithm::detail::token_finderF<boost::algorithm::detail::is_any_ofF<wchar_t>>,
FunctionObj=boost::algorithm::detail::token_finderF<boost::algorithm::detail::is_any_ofF<wchar_t>>
]
c:\boost\boost\function\function_template.hpp(906) : see reference to function template instantiation 'bool boost::detail::function::basic_vtable2<R,T0,T1>::assign_to<Functor>(F,boost::detail::function::function_buffer &)' being compiled
with
[
R=boost::iterator_range<std::_String_iterator<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t>>>,
T0=std::_String_iterator<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t>>,
T1=std::_String_iterator<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t>>,
Functor=boost::algorithm::detail::token_finderF<boost::algorithm::detail::is_any_ofF<wchar_t>>,
F=boost::algorithm::detail::token_finderF<boost::algorithm::detail::is_any_ofF<wchar_t>>
]
c:\boost\boost\function\function_template.hpp(720) : see reference to function template instantiation 'void boost::function2<R,T0,T1>::assign_to<Functor>(Functor)' being compiled
with
[
R=boost::iterator_range<std::_String_iterator<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t>>>,
T0=std::_String_iterator<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t>>,
T1=std::_String_iterator<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t>>,
Functor=boost::algorithm::detail::token_finderF<boost::algorithm::detail::is_any_ofF<wchar_t>>
]
c:\boost\boost\algorithm\string\detail\find_iterator.hpp(51) : see reference to function template instantiation 'boost::function2<R,T0,T1>::function2<FinderT>(Functor,int)' being compiled
with
[
R=boost::iterator_range<std::_String_iterator<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t>>>,
T0=std::_String_iterator<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t>>,
T1=std::_String_iterator<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t>>,
FinderT=boost::algorithm::detail::token_finderF<boost::algorithm::detail::is_any_ofF<wchar_t>>,
Functor=boost::algorithm::detail::token_finderF<boost::algorithm::detail::is_any_ofF<wchar_t>>
]
c:\boost\boost\algorithm\string\find_iterator.hpp(261) : see reference to function template instantiation 'boost::algorithm::detail::find_iterator_base<IteratorT>::find_iterator_base<FinderT>(FinderT,int)' being compiled
with
[
IteratorT=input_iterator_type,
FinderT=boost::algorithm::detail::token_finderF<boost::algorithm::detail::is_any_ofF<wchar_t>>
]
c:\boost\boost\algorithm\string\iter_find.hpp(167) : see reference to function template instantiation 'boost::algorithm::split_iterator<IteratorT>::split_iterator<FinderT>(IteratorT,IteratorT,FinderT)' being compiled
with
[
IteratorT=input_iterator_type,
FinderT=boost::algorithm::detail::token_finderF<boost::algorithm::detail::is_any_ofF<wchar_t>>
]
c:\boost\boost\algorithm\string\split.hpp(149) : see reference to function template instantiation 'SequenceSequenceT &boost::algorithm::iter_split<SequenceSequenceT,RangeT,boost::algorithm::detail::token_finderF<PredicateT>>(SequenceSequenceT &,RangeT &,FinderT)' being compiled
with
[
SequenceSequenceT=std::vector<std::wstring>,
RangeT=std::wstring,
PredicateT=boost::algorithm::detail::is_any_ofF<wchar_t>,
FinderT=boost::algorithm::detail::token_finderF<boost::algorithm::detail::is_any_ofF<wchar_t>>
]
c:\documents and settings\user\my documents\visual studio 2008\projects\pevfind\pevfind\consoleparser.cpp(1529) : see reference to function template instantiation 'SequenceSequenceT &boost::algorithm::split<std::vector<_Ty>,std::wstring,boost::algorithm::detail::is_any_ofF<CharT>>(SequenceSequenceT &,RangeT &,PredicateT,boost::algorithm::token_compress_mode_type)' being compiled
with
[
SequenceSequenceT=std::vector<std::wstring>,
_Ty=std::wstring,
CharT=wchar_t,
RangeT=std::wstring,
PredicateT=boost::algorithm::detail::is_any_ofF<wchar_t>
]
c:\boost\boost\utility\addressof.hpp(30) : warning C4512: 'boost::detail::addr_impl_ref<T>' : assignment operator could not be generated
with
[
T=boost::algorithm::detail::token_finderF<boost::algorithm::detail::is_any_ofF<wchar_t>>
]
Your compile failed because there's a new warning being emitted (boost::detail::addr_impl_ref<T>' : assignment operator could not be generated), and your settings are set to treat warnings as errors. Judging from this and this, it's indeed an issue with Boost 1.39.0 and VS2008.
The latter link provides a patch that fixes the issue. It should be fixed in Boost 1.40.0.
The alternative would be to disable the "treat warnings as errors" flag temporarily.
If I switch to warning level 4 and set treat warnings as errors mine breaks too.
Try changing those settings.
I really don't like "treat warnings as errors" for this kind of reason, but you can just do:
#pragma warning (disable:4512)
above any #include line for addressof.hpp.