Filling std::map with std::transform (error: cannot deduce argument) - c++

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.

Related

User-defined types with {fmt} library and Visual Studio 2022 (17.2.2)

I am using https://github.com/fmtlib/fmt (commit hash 7e4ad40171aa552d38cb99a5c181a0d7b150facc - at the time of this writing pretty new) with the newest Visual Studio 2022 version (17.2.2) and following this tutorial here
I want to get this working:
struct complex
{
double a;
double b;
};
template<>
struct fmt::formatter<complex>
{
template<typename ParseContext>
constexpr auto parse(ParseContext& ctx) { return ctx.begin(); }
template<typename FormatContext>
auto format(complex const& number, FormatContext& ctx) {
return format_to(ctx.out(), "{0} +i{1}", number.a, number.b);
}
};
// ...
// somewhere in main
complex number{1, 2};
std::string message = fmt::format("The number is {}.\n", number);
I get the error message:
ERROR: G:/dev/piper/devertexwahn/flatland/tests/third_party/BUILD.bazel:42:8: Compiling flatland/tests/third_party/fmt_test.cpp failed: (Exit 2): cl.exe failed: error executing command C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.32.31326\bin\HostX64\x64\cl.exe /nologo /DCOMPILER_MSVC /DNOMINMAX /D_WIN32_WINNT=0x0601 /D_CRT_SECURE_NO_DEPRECATE ... (remaining 44 arguments skipped)
flatland/tests/third_party/fmt_test.cpp(53): error C2668: 'std::format_to': ambiguous call to overloaded function
C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.32.31326\include\format(3046): note: could be '_OutputIt std::format_to<OutputIt,const double&,const double&>(_OutputIt,const std::_Basic_format_string<char,const double &,const double &>,const double &,const double &)' [found using argument-dependent lookup]
with
[
_OutputIt=fmt::v8::appender,
OutputIt=fmt::v8::appender
]
G:\bazel_output_base\execroot\de_vertexwahn\bazel-out\x64_windows-fastbuild\bin\external\fmt\_virtual_includes\fmt\fmt/core.h(3195): note: or 'OutputIt fmt::v8::format_to<OutputIt,const double&,const double&,0>(OutputIt,fmt::v8::basic_format_string<char,const double &,const double &>,const double &,const double &)'
with
[
OutputIt=fmt::v8::appender
]
flatland/tests/third_party/fmt_test.cpp(52): note: while trying to match the argument list '(OutputIt, const char [10], const double, const double)'
with
[
OutputIt=fmt::v8::appender
]
G:\bazel_output_base\execroot\de_vertexwahn\bazel-out\x64_windows-fastbuild\bin\external\fmt\_virtual_includes\fmt\fmt/core.h(713): note: see reference to function template instantiation 'auto fmt::v8::formatter<complex,char,void>::format<Context>(const complex &,FormatContext &)' being compiled
with
[
Context=fmt::v8::format_context,
FormatContext=fmt::v8::format_context
]
G:\bazel_output_base\execroot\de_vertexwahn\bazel-out\x64_windows-fastbuild\bin\external\fmt\_virtual_includes\fmt\fmt/core.h(1457): note: see reference to function template instantiation 'bool fmt::v8::detail::has_const_formatter<U,Context>(void)' being compiled
with
[
U=complex,
Context=fmt::v8::format_context
]
G:\bazel_output_base\execroot\de_vertexwahn\bazel-out\x64_windows-fastbuild\bin\external\fmt\_virtual_includes\fmt\fmt/core.h(1486): note: see reference to class template instantiation 'fmt::v8::detail::arg_mapper<Context>::formattable<const complex &,complex>' being compiled
with
[
Context=fmt::v8::format_context
]
G:\bazel_output_base\execroot\de_vertexwahn\bazel-out\x64_windows-fastbuild\bin\external\fmt\_virtual_includes\fmt\fmt/core.h(1697): note: see reference to alias template instantiation 'fmt::v8::detail::mapped_type_constant<complex,Context>' being compiled
with
[
Context=fmt::v8::format_context
]
G:\bazel_output_base\execroot\de_vertexwahn\bazel-out\x64_windows-fastbuild\bin\external\fmt\_virtual_includes\fmt\fmt/core.h(1858): note: see reference to function template instantiation 'unsigned __int64 fmt::v8::detail::encode_types<Context,complex,>(void)' being compiled
with
[
Context=fmt::v8::format_context
]
G:\bazel_output_base\execroot\de_vertexwahn\bazel-out\x64_windows-fastbuild\bin\external\fmt\_virtual_includes\fmt\fmt/core.h(3167): note: see reference to class template instantiation 'fmt::v8::format_arg_store<fmt::v8::format_context,complex>' being compiled
flatland/tests/third_party/fmt_test.cpp(59): note: see reference to function template instantiation 'std::string fmt::v8::format<complex&>(fmt::v8::basic_format_string<char,complex &>,complex &)' being compiled
G:\bazel_output_base\execroot\de_vertexwahn\bazel-out\x64_windows-fastbuild\bin\external\fmt\_virtual_includes\fmt\fmt/core.h(1696): error C2062: type 'unknown-type' unexpected
G:\bazel_output_base\execroot\de_vertexwahn\bazel-out\x64_windows-fastbuild\bin\external\fmt\_virtual_includes\fmt\fmt/core.h(1696): error C2144: syntax error: 'unknown-type' should be preceded by '('
G:\bazel_output_base\execroot\de_vertexwahn\bazel-out\x64_windows-fastbuild\bin\external\fmt\_virtual_includes\fmt\fmt/core.h(1697): error C2039: 'value': is not a member of '`global namespace''
G:\bazel_output_base\execroot\de_vertexwahn\bazel-out\x64_windows-fastbuild\bin\external\fmt\_virtual_includes\fmt\fmt/core.h(1855): error C3615: constexpr function 'fmt::v8::detail::encode_types' cannot result in a constant expression
G:\bazel_output_base\execroot\de_vertexwahn\bazel-out\x64_windows-fastbuild\bin\external\fmt\_virtual_includes\fmt\fmt/core.h(1858): note: failure was caused by control reaching the end of a constexpr function
Target //flatland/tests/third_party:fmt_test failed to build
Use --verbose_failures to see the command lines of failed build steps.
The code seems to work with GCC9 on Ubuntu 20.04 and with Apple CLang on macOS. Any ideas what I am doing wrong here?
The error is caused by the std::format_to function introduced in C++20. To fix it, qualify your calls to fmt::format_to. For example, instead of
return format_to(ctx.out(), "{0} +i{1}", number.a, number.b);
do this instead:
return fmt::format_to(ctx.out(), "{0} +i{1}", number.a, number.b);
See this issue for more info: format conflict with Visual Studio 2022 17.2.0.

Errors when compiling catch with Visual Studio 2008

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.

Confirm This Standard Library Bug Relating to Allocators in MSVC 2015 RC

Here is a SSCCE:
#include <memory>
#include <vector>
template <class T> struct my_allocator : std::allocator<T> {
//This overriding struct causes the error
template <class U> struct rebind {
typedef my_allocator<T> other;
};
//Ignore all this.
typedef std::allocator<T> base;
typename base::pointer allocate(typename base::size_type n, std::allocator<void>::const_pointer /*hint*/=nullptr) { return (T*)malloc(sizeof(T)*n); }
void deallocate(typename base::pointer p, typename base::size_type /*n*/) { free(p); }
};
int main(int /*argc*/, char* /*argv*/[]) {
std::vector<int,my_allocator<int>> vec;
return 0;
}
GCC likes it.
ICC likes it.
Clang likes it.
Even MSVC 2013 likes it.
But MSVC 2015 RC spits out:
1>------ Build started: Project: Test Alloc, Configuration: Debug Win32 ------
1> main.cpp
1>c:\program files (x86)\microsoft visual studio 14.0\vc\include\vector(579): error C2664: 'void std::_Wrap_alloc<my_allocator<int>>::deallocate(int *,unsigned int)': cannot convert argument 1 from 'std::_Container_proxy *' to 'int *'
1> c:\program files (x86)\microsoft visual studio 14.0\vc\include\vector(579): note: Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
1> c:\program files (x86)\microsoft visual studio 14.0\vc\include\vector(574): note: while compiling class template member function 'void std::_Vector_alloc<std::_Vec_base_types<_Ty,_Alloc>>::_Free_proxy(void)'
1> with
1> [
1> _Ty=int,
1> _Alloc=my_allocator<int>
1> ]
1> c:\program files (x86)\microsoft visual studio 14.0\vc\include\vector(541): note: see reference to function template instantiation 'void std::_Vector_alloc<std::_Vec_base_types<_Ty,_Alloc>>::_Free_proxy(void)' being compiled
1> with
1> [
1> _Ty=int,
1> _Alloc=my_allocator<int>
1> ]
1> c:\program files (x86)\microsoft visual studio 14.0\vc\include\vector(668): note: see reference to class template instantiation 'std::_Vector_alloc<std::_Vec_base_types<_Ty,_Alloc>>' being compiled
1> with
1> [
1> _Ty=int,
1> _Alloc=my_allocator<int>
1> ]
1> c:\users\ian mallett\desktop\test-alloc\main.cpp(18): note: see reference to class template instantiation 'std::vector<int,my_allocator<int>>' being compiled
Related program give similarly fishy sounding errors. Here are two:
error C2664: 'void std::_Wrap_alloc>::deallocate(int *,unsigned int)': cannot convert argument 1 from 'std::_Container_proxy *' to 'int *'
cannot convert argument 1 from 'std::_Wrap_alloc>' to 'const aligned_allocator &'
Boolean question: is this a bug? Iff it is, I will (try) to submit it.
[EDIT: as noted in the comments, this only occurs in debug mode. In release mode, it compiles and executes fine.]
[EDIT: much simpler example]
Boolean question: is this a bug?
false.
Although the template error given by MSVC here is surpassingly unhelpful, the error here is mine (reassuring since this version of the standard library is shipping today).
I created this allocator (and later, the reduced test case) from a variety of sources, which is why I assumed it was correct. However, as suggested in the comments, I checked again, this time exhaustively against the documentation.
The missing component here is one of the copy constructors (the template one that can't be auto-generated). This only shows up when the rebind struct is defined since the rebind struct overrides the same struct in the parent class (which, since it's in the parent class, ultimately causes the parent's copy constructor to be called, so there's no problem (except that it's technically wrong)).
The interesting thing here is that the error didn't occur until now. As I said, GCC, Clang, and MSVC 2013 all like it (even with their respective debug modes). It's just that none of these happened to call the template copy constructor. Nevertheless, it is specified by the standard, so again, the error is ultimately mine.
Congratulations to the MSVC compiler team, and sorry for the noise! :D

(Default) construct an object for every variadic type

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.

std::find on std::vector< std::string > does not compile in Visual C++ 2008?

I tried this code on Visual C++ 2008 express edition, but it does not compile:
#include <iostream>
#include <vector>
#include <algorithm>
int main()
{
typedef std::string Element;
typedef std::vector< Element > Vector;
typedef Vector::iterator Iterator;
Vector v;
std::find( v.begin(), v.end(), std::string( "xxx" ) );
return 0;
}
I get the following error:
c:\programmi\microsoft visual studio 9.0\vc\include\algorithm(40) : error C2784: 'bool std::operator ==(const std::vector<_Ty,_Alloc> &,const std::vector<_Ty,_Alloc> &)' : could not deduce template argument for 'const std::vector<_Ty,_Alloc> &' from 'std::basic_string<_Elem,_Traits,_Ax>'
The same code is corrected compiled by gcc and works as expected.
Is it a bug of Visual Studio? And how can I get my example working on Visual C++ 2008?
You forgot to #include <string>.
You must always include all the headers that you need for your code. Never depend on magic recursive inclusions that happen to work sometimes. For everything you use in your code you must know where it has been declared and guarantee that the declarations are visible in your translation unit.