std::forward compiling error VS2010 - c++

I am getting a weird error that I can't understand(since it's from a native file of VS) from file utility(it's located in C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\), it is being compiled in my project with Visual C++ 10.0.
'std::forward' : cannot convert parameter 1 from '' to '&'
template<class _Other1, class _Other2>
pair(_Other1&& _Val1, _Other2&& _Val2)
: _Mybase(_STD forward<_Other1>(_Val1), _STD forward<_Other2>(_Val2))
{ // construct from moved values
}
Can anyone explain this error? It seems to me very strange, but I'm totally new to C++ and I don't understand how to fix it.
The error seems to be here:
std::map<std::string, DWORD>::value_type("SOME_STRING", 8192);
And the compilation reports this:
see reference to function template instantiation
'std::pair<_Ty1,_Ty2>::pair<const char(&)[12],>(_Other1,_Other2 &&)'
being compiled with
[
_Ty1=const std::string,
_Ty2=DWORD,
_Other1=const char (&)[12],
_Other2=
]

It seems the compiler is incapable of coping with the string literal passed in. I don't know whether it's a bug in the standard library implementation VS2010 uses, or whether it hits an edge case in the standard (and is actually supposed to fail), but either way, you can solve it by explicitly creating a std::string from the literal:
std::map<std::string, DWORD>::value_type(std::string("SOME_STRING"), 8192);

Related

Locating error in source which is boost related [duplicate]

This question already has answers here:
C++ Boost: what's the cause of this warning?
(6 answers)
Closed 2 years ago.
I'm porting an old project from Boost 1.48 to Boost 1.61. The project is compiled using MSVC 2013. There are several reported errors during build which I think are boost related but unfortunately the bug reports are not very helpful at all.
3> entry.cpp
4>c:\program files (x86)\microsoft visual studio 12.0\vc\include\xutility(2715): error C2220: warning treated as error - no 'object' file generated
4>c:\program files (x86)\microsoft visual studio 12.0\vc\include\xutility(2715): warning C4996: 'std::_Fill_n': Function call with parameters that may be unsafe - this call relies on the caller to check that the passed values are correct. To disable this warning, use -D_SCL_SECURE_NO_WARNINGS. See documentation on how to use Visual C++ 'Checked Iterators'
4> c:\program files (x86)\microsoft visual studio 12.0\vc\include\xutility(2701) : see declaration of 'std::_Fill_n'
4> c:\boost\boost_1_61_0\boost\random\detail\polynomial.hpp(114) : see reference to function template instantiation '_OutIt std::fill_n<boost::random::detail::polynomial_ops::digit_t*,size_t,boost::random::detail::polynomial_ops::digit_t>(_OutIt,_Diff,const _Ty &)' being compiled
4> with
4> [
4> _OutIt=boost::random::detail::polynomial_ops::digit_t *
4> , _Diff=size_t
4> , _Ty=boost::random::detail::polynomial_ops::digit_t
4> ]
I cannot see anything in the above that helps me identify where the problem is, there are no line numbers and the snippet of code is not from the compiled file.
#Eljay, does it have a human readable text option I could locate in the IDE? – SPlatten 43 mins ago
The thing you posted IS human readable text. It actually describes a warning with a reference to documentation. ¯\(ツ)/¯ Maybe you can just tell the compiler you don't want to receive warnings
In addition, you can use the keywords to google additional information:
C++ Boost: what's the cause of this warning?
Many libraries in addition already have a warning-suppression header (look for e.g. boost/iostreams/detail/config/disable_warnings.hpp or boost/random/detail/disable_warnings.hpp). The fact that known benign warnings "slip through" might indicate that the library needs to update their suppressions, OR you might need to upgrade your boost version.

attempting to reference a deleted function for atomic c++

I have a piece of code that use to work for Visual Studio 2013. Now that I'm trying to build the same code in Visual Studio 2017 it complains. Here is the code I'm trying to do.
#include <array>
#include <atomic>
int main()
{
using TrdRobotStateArray = std::array<std::atomic<double>, 6>;
TrdRobotStateArray mCurrentPose = { 0.3 };
printf("%0.3f", mCurrentPose[0]);
return 0;
}
With this, I get this error:
error C2280: 'std::atomic<double>::atomic(const std::atomic<double> &)': attempting to reference a deleted function
I didn't write this code, and I'm trying to read into atomic variables. But I'm still not quite sure what is going on with the error. An explanation about atomics would be greatly appreciated. Thanks!
update:
Here are all the errors and warnings that came with this code. So it would help others in the future.
1>AtomicTest.cpp
1>AtomicTest.cpp(13): error C4839: non-standard use of class
'std::atomic<double>' as an argument to a variadic function
1>AtomicTest.cpp(13): note: the constructor and destructor will not be
called; a bitwise copy of the class will be passed as the argument
1>AtomicTest.cpp(11): note: see declaration of 'std::atomic<double>'
1>AtomicTest.cpp(13): error C2280: 'std::atomic<double>::atomic(const
std::atomic<double> &)': attempting to reference a deleted function
1>C:\Program Files (x86)\Microsoft Visual
Studio\2017\Professional\VC\Tools\MSVC\14.11.25503\include\atomic(689):
note: see declaration of 'std::atomic<double>::atomic'
1>C:\Program Files (x86)\Microsoft Visual
Studio\2017\Professional\VC\Tools\MSVC\14.11.25503\include\atomic(689):
note: 'std::atomic<double>::atomic(const std::atomic<double> &)': function
was explicitly deleted
1>AtomicTest.cpp(13): warning C4477: 'printf' : format string '%0.3f'
requires an argument of type 'double', but variadic argument 1 has type
'std::atomic<double>'
1>Done building project "AtomicTest.vcxproj" -- FAILED.
You have to load the value explicitely in order to compile it:
printf("%0.3d", mCurrentPose[0].load());
Otherwise, it will try to copy the atomic variable itself for printf() which clearly is not the intent.
Atomic variables are not CopyConstructible.
This is a requirement of the C++ standard, so VisualStudio 2017 is correct.

C++, curious compiler error when implementing a function `int next(std::string param)`

I've been badly bitten by the following code, on which I wasted many hours of precious time.
#include<string>
int next(std::string param){
return 0;
}
void foo(){
next(std::string{ "abc" });
}
This produces the following compiler error (on Visual Studio 2013):
1>------ Build started: Project: sandbox, Configuration: Debug Win32 ------
1> test.cpp
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\xutility(371): error C2039: 'iterator_category' : is not a member of 'std::basic_string<char,std::char_traits<char>,std::allocator<char>>'
1> c:\users\ray\dropbox\programming\c++\sandbox\test.cpp(8) : see reference to class template instantiation 'std::iterator_traits<std::basic_string<char,std::char_traits<char>,std::allocator<char>>>' being compiled
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\xutility(371): error C2146: syntax error : missing ';' before identifier 'iterator_category'
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\xutility(371): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\xutility(371): error C2602: 'std::iterator_traits<std::basic_string<char,std::char_traits<char>,std::allocator<char>>>::iterator_category' is not a member of a base class of 'std::iterator_traits<std::basic_string<char,std::char_traits<char>,std::allocator<char>>>'
1> c:\program files (x86)\microsoft visual studio 12.0\vc\include\xutility(371) : see declaration of 'std::iterator_traits<std::basic_string<char,std::char_traits<char>,std::allocator<char>>>::iterator_category'
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\xutility(371): error C2868: 'std::iterator_traits<std::basic_string<char,std::char_traits<char>,std::allocator<char>>>::iterator_category' : illegal syntax for using-declaration; expected qualified-name
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
I found out later that if I change my function name from next() to something else, all is fine. To me, this indicates that there is a name conflict, specifically of the name next. I find this strange because I didn't use anything like using namespace std. As far as I know, next is not a built-in C++ keyword (is it?). I looked up next here, but it's std::next and as I said I didn't using namespace std. So how did this conflict happen? How do I prevent similar things in the future? What other names might cause a conflict like this?
There are several things going on here, interacting in subtle ways.
Firstly, an unqualified call to next with an argument of type std::string means that as well as your own next function, the standard function template std::next is found by Argument-dependent lookup (ADL).
After name lookup has found your ::next and the standard library's std::next it performs overload resolution to see which one is a better match for the arguments you called it with.
The definition of std::next looks like:
template <class ForwardIterator>
ForwardIterator next(ForwardIterator x,
typename std::iterator_traits<ForwardIterator>::difference_type n = 1);
This means that when the compiler performs overload resolution it substitutes the type std::string into std::iterator_traits<std::string>.
Prior to C++14 iterator_traits is not SFINAE-friendly which means that it is invalid to instantiate it with a type that is not an iterator. std::string is not an iterator, so it's invalid. The SFINAE rule does not apply here, because the error is not in the immediate context, and so using iterator_traits<T>::difference_type for any non-iterator T will produce a hard error, not a substitution failure.
Your code should work correctly in C++14, or using a different standard library implementation that already provides a SFINAE-friendly iterator_traits, such as GCC's library. I believe Microsoft will also provide a SFINAE-friendly iterator_traits for the next major release of Visual Studio.
To make your code work now you can qualify the call to next so ADL is not performed:
::next(std::string{ "abc" });
This says to call the next in the global namespace, rather than any other next that might be found by unqualified name lookup.
(Updated per Jonathan's comments)
There are two views here, the C++11 and the C++14 view. Back in 2013, C++11's std::next was not properly defined. It is supposed to apply to iterators, but due to what looks like an oversight it will cause hard failures when you pass it a non-iterator. I believe the intention was that SFINAE should have prevented this; std::iterator_traits<X> should cause substitution failures.
In C++14, this problem is solved. The definition of std::next hasn't changed, but it's second argument (std::iterator_traits<>) is now properly empty for non-iterators. This eliminates std::next from the overload set for non-iterators.
The relevant declaration (taken from VS2013) is
template<class _FwdIt> inline
_FwdIt next(_FwdIt _First,
typename iterator_traits<_FwdIt>::difference_type _Off = 1)
This function should be added to the overload set if it can be instantiated for the given arguments.
The function is found via Argument Dependent Lookup and Microsoft's header structure. They put std::next in <xutility> which is shared between <string> and <iterator>
Note: _FwdIt and _Off are part of the implementation namespace. Don't use leading underscores yourself.
Actually std::next() is a function defined in <iterator> which returns the next iterator passed to std::next(). Your code is running on my computer with gcc-4.9.2. More : http://en.cppreference.com/w/cpp/iterator/next
The code I used:
#include<string>
#include <iostream>
int next(std::string param){
std::cout<<param<<std::endl;
return 0;
}
void foo(){
next(std::string{ "abc" });
}
int main()
{
foo();
return 0;
}
Also on ideone : http://ideone.com/QVxbO4
The compiler found standard function std::next due to the so-called Argument Dependent Lookup because the argument used in the call - std::string - is declared in namespace std.

How can I test the portability of a C++ codebase developed and managed in Visual Studio 2010?

I have a very large and very old C++ project currently maintained in Visual Studio 2010. One member of our team has just tested the bumpiness of the upgrade path to VS 2012, and found we were being affected by this, through our use of Microsoft's non-standard extensions to the language.
Is there any tool we can run over our codebase that will tell us how many other non-standard extensions we're using, so we can eliminate them before they cause us any more problems?
Specify the compiler switch /Za which disables extensions.
For example, the following code:
#include <string>
void f(std::string&) {}
int main()
{
f(std::string("hello"));
}
Compiles (with warning) when /Za is not specified but fails to compile when /Za is specified with the following error:
main.cpp(7) : error C2664: 'f' : cannot convert parameter 1 from 'std::basic_string<_Elem,_Traits,_Ax>' to 'std::string &'
with
[
_Elem=char,
_Traits=std::char_traits,
_Ax=std::allocator
]
A non-const reference may only be bound to an lvalue

Tools to generate higher-quality error messages for template-based code?

Concepts, that would render these tools unnecessary, are not part of C++11.
STLFilt would have been one option but it is no longer maintained.
Clang claims to give expressive diagnostics although important C++11 features are not available yet.
colorgcc seems to be abandoned since 1999.
What production quality tools are available to decipher error messages stemming from template-based code? Eclipse-CDT support would be nice too. :)
If I give up on C++11, what options do I have for C++98?
Related questions:
Deciphering C++ template error messages
Improving g++ output
Let's have a stab at an answer (I marked this community wiki so we get a good response together)...
I'm working since a long time with templates and error messages have generally improved in some way or another:
Writing a stack of errors creates a lot more text but also typically includes the level the user is looking at and this generally includes a hint at what the actual problem is. Given that the compiler only sees a translation unit tossed at it, there isn't a lot which can be done determining which error in the stack is the one most suitable for the user.
Using concept checkers, i.e. classes or functions which exercise all the required members of template arguments and possibly generating errors messages using static_assert() give the template author a way to tell users about assumptions which apparently don't hold.
Telling the user about types he writes rather than expanding all typedefs as the compiler like to see at the lowest level also helps. clang is rather good at this and actually gives you error messages e.g. talking about std::string rather than expanding things type to whatever it ends up to be.
A combination of the technique actually causes e.g. clang to create quite decent error message (even if it doesn't implement C++2011, yet; however, no compiler does and as far as I can tell gcc and clang are leading the pack). I know other compiler developers actively work on improving the template error messages as lots of programmers have discovered that templates actually are a huge leap forward even though the error messages are something which takes a bit of getting used to.
One problem tools like stlfilt face is that C++ compilers and libraries are under active development. This results in error messages shifting all the time, causing the tool to receive different outputs. While it is good that compiler writers work on improving error messages, it certainly makes life harder for people who try to work from the error messages they got. There is another side to this as well: once a certain error pattern is detected to be common and is picked up e.g. by stlfilt (well, it isn't actively maintained as far as I know) compiler writers are probably keen to report the errors following these patterns directly, possibly also providing additional information available to the compiler but not emitted before. Put differently, I would expect that compiler writers are quite receptive to reports from users describing common error situations and how they are best reported. The compiler writers may not encounter the errors themselves because the code they are working on is actually C (e.g. gcc is implemented in C) or because they are so used to certain template techniques that they avoid certain errors (e.g. omission of typename for dependent types).
Finally, to address the question about concrete tools: the main "tool" I'm using when I get kind of stuck with a compiler complaining about some template instantiation is to use different compilers! Although it isn't always the case but often one compiler reports an entirely incomprehensible error messages which only makes sense after seeing the fairly concise report from another compiler (in case you are interested, I regularly use recent version of gcc, clang, and EDG for this). I'm not aware of a readily packaged too like stlfilt, however.
I know this may not be as helpful as you wanted, but I've found the best tool against template error messages is knowledge.
A good understanding of the STL and how to use it will help you avoid lots of errors in the first place. Secondly, often error messages refer to functions in the STL source - if you have a rough idea how the STL is implemented, this can be extremely helpful in deciphering what the error message is going on about. Finally, compiler makers are aware of this issue and are gradually improving error message output, so you would do well to stick to the latest version of your compiler.
Here's a good example of an obscure template error:
std::vector<std::unique_ptr<int>> foo;
std::vector<std::unique_ptr<int>> bar = foo;
unique_ptr is not copyable, it can only be moved. So trying to assign a vector of unique_ptr to another vector will mean somewhere in the vector source code will try to copy a unique pointer. Therefore the error will originate from code which is not yours and throw a fairly opaque error message as a result. The ideal error message would be
main.cpp(20): cannot construct 'bar' from 'foo': foo's template type is non-copyable
Instead, VS2010 gives the following error:
1>C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\xmemory(48): error C2248: 'std::unique_ptr<_Ty>::unique_ptr' : cannot access private member declared in class 'std::unique_ptr<_Ty>'
1> with
1> [
1> _Ty=int
1> ]
1> C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\memory(2347) : see declaration of 'std::unique_ptr<_Ty>::unique_ptr'
1> with
1> [
1> _Ty=int
1> ]
1> C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\xmemory(197) : see reference to function template instantiation 'void std::_Construct<std::unique_ptr<_Ty>,const std::unique_ptr<_Ty>&>(_Ty1 *,_Ty2)' being compiled
1> with
1> [
1> _Ty=int,
1> _Ty1=std::unique_ptr<int>,
1> _Ty2=const std::unique_ptr<int> &
1> ]
1> C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\xmemory(196) : while compiling class template member function 'void std::allocator<_Ty>::construct(std::unique_ptr<int> *,const _Ty &)'
1> with
1> [
1> _Ty=std::unique_ptr<int>
1> ]
1> C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\vector(421) : see reference to class template instantiation 'std::allocator<_Ty>' being compiled
1> with
1> [
1> _Ty=std::unique_ptr<int>
1> ]
1> C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\vector(481) : see reference to class template instantiation 'std::_Vector_val<_Ty,_Alloc>' being compiled
1> with
1> [
1> _Ty=std::unique_ptr<int>,
1> _Alloc=std::allocator<std::unique_ptr<int>>
1> ]
1> main.cpp(19) : see reference to class template instantiation 'std::vector<_Ty>' being compiled
1> with
1> [
1> _Ty=std::unique_ptr<int>
1> ]
Sifting through this there are clues. The first section references a private member access of std::unique_ptr<int>. The second section, if you click through to the source line, points at the copy constructor of unique_ptr, which is declared beneath a private: specifier. So now we know we tried to copy a unique_ptr which is not allowed. Sections 3, 4 and 5 just point to boilerplate code - it's just noise. Section 6 says "see reference to class template instantiation 'std::_Vector_val<_Ty,_Alloc>' being compiled". In other words, this error happened in vector's template code. The last section is most interesting: it directly points at the line declaring foo in your own source code - it's figured out where in your own source code the error originated from!
So adding up the clues:
It originates in foo,
It originates in vector code,
It tries to copy a unique_ptr which is not allowed.
Conclusion: the vector tried to copy one of its elements, which is not allowed. Review code for foo and check for anything causing a copy.
Since the compiler only pointed at foo's declaration, if the assignment is far away in the source code some hunting will be involved. This obviously is not ideal, but I think this approach ultimately gives you more chance of fixing mistakes in general. You'll start to recognise that kind of error dump means "you copied a unique_ptr". Again, I'm not defending it, it definitely needs improving - but I think these days there's just enough information in the output that combined with a good knowledge of the STL allows you to fix the problem.
I have found Clang to generate the best error messages for heavily templated code.
Of course verbosity is unavoidable in most cases, but it's still better than GCC or MSVC most of the time. Here's the Clang error message for the example code posted by AshleysBrain:
$ clang++ -std=c++11 -stdlib=libc++ -o dummy dummy.cpp
In file included from dummy.cpp:1:
In file included from /usr/include/c++/v1/vector:243:
In file included from /usr/include/c++/v1/__bit_reference:15:
In file included from /usr/include/c++/v1/algorithm:594:
/usr/include/c++/v1/memory:1425:36: error: calling a private constructor of class 'std::__1::unique_ptr<int,
std::__1::default_delete<int> >'
::new ((void*)__p) _Tp(_STD::forward<_Args>(__args)...);
^
/usr/include/c++/v1/memory:1358:14: note: in instantiation of function template specialization
'std::__1::allocator_traits<std::__1::allocator<std::__1::unique_ptr<int, std::__1::default_delete<int> > >
>::__construct<std::__1::unique_ptr<int, std::__1::default_delete<int> >, std::__1::unique_ptr<int,
std::__1::default_delete<int> > &>' requested here
{__construct(__has_construct<allocator_type, pointer, _Args...>(),
^
/usr/include/c++/v1/vector:781:25: note: in instantiation of function template specialization
'std::__1::allocator_traits<std::__1::allocator<std::__1::unique_ptr<int, std::__1::default_delete<int> > >
>::construct<std::__1::unique_ptr<int, std::__1::default_delete<int> >, std::__1::unique_ptr<int,
std::__1::default_delete<int> > &>' requested here
__alloc_traits::construct(__a, _STD::__to_raw_pointer(this->__end_), *__first);
^
/usr/include/c++/v1/vector:924:9: note: in instantiation of function template specialization
'std::__1::vector<std::__1::unique_ptr<int, std::__1::default_delete<int> >,
std::__1::allocator<std::__1::unique_ptr<int, std::__1::default_delete<int> > >
>::__construct_at_end<std::__1::unique_ptr<int, std::__1::default_delete<int> > *>' requested here
__construct_at_end(__x.__begin_, __x.__end_);
^
dummy.cpp:7:37: note: in instantiation of member function 'std::__1::vector<std::__1::unique_ptr<int,
std::__1::default_delete<int> >, std::__1::allocator<std::__1::unique_ptr<int, std::__1::default_delete<int> > >
>::vector' requested here
std::vector<unique_ptr<int>> bar = foo;
^
/usr/include/c++/v1/memory:1997:5: note: declared private here
unique_ptr(const unique_ptr&);
^
1 error generated.
It's still long and ugly, but in my opinion much clearer regarding what/where the problem is.