Using c++17 'structured bindings' feature in visual studio 2017 - c++

I'm trying to utilize some c++17 features such as structured bindings in my code but the compiler keeps giving me errors and I'm not sure if it's because I'm doing things wrong or if I haven't setup c++17 properly to work in VS17. The simple code I'm trying to compile is this:
#include <iostream>
struct S
{
int i = 0;
float f = 32.0f;
};
int main()
{
S s;
auto [i, f] = s();
std::cin.get();
return 0;
}
From the understanding of this article, this is how I would use the new c++17 syntax to return multiple values. However, I keep getting these errors:
c:\users\jason\documents\visual studio 2017\projects\consoleapplication1\consoleapplication1\consoleapplication1.cpp(16): error C2059: syntax error: 'empty declaration'
1>c:\users\jason\documents\visual studio 2017\projects\consoleapplication1\consoleapplication1\consoleapplication1.cpp(16): error C2143: syntax error: missing ';' before '['
1>c:\users\jason\documents\visual studio 2017\projects\consoleapplication1\consoleapplication1\consoleapplication1.cpp(16): warning C4467: usage of ATL attributes is deprecated
1>c:\users\jason\documents\visual studio 2017\projects\consoleapplication1\consoleapplication1\consoleapplication1.cpp(16): error C2337: 'i': attribute not found
1>c:\users\jason\documents\visual studio 2017\projects\consoleapplication1\consoleapplication1\consoleapplication1.cpp(16): error C2337: 'f': attribute not found
1>c:\users\jason\documents\visual studio 2017\projects\consoleapplication1\consoleapplication1\consoleapplication1.cpp(16): error C2059: syntax error: '='
I've also tried setting the compiler switch to std:/c++latest inside the properties of the project but still no dice. What I'm I doing wrong?

As #KerrekSB noted in the comments, auto [i, f] = s(); should be auto [i, f] = s;.
You said that you're using VS2017 but then indicated that your compiler version is 19.00.24218, which is actually VS2015 Update 3... VC++ did not support structured bindings until VS2017 Update 3 (compiler v19.11.25503) — you need to update (or fix your project settings and/or build environment so that the correct compiler is used).

Only did a quick look at the page you linked but seems like you should have it like this:
#include <iostream>
struct S
{
int i = 0;
float f = 32.0f;
};
int main()
{
S s(); <--- You were missing the ()
auto [i, f] = s();
std::cin.get();
return 0;
}

Related

why type casting on non-pointer struct give syntax error

I am using Visual C++ express 2008 try to compile code similar to below:
no problem
{
...
AVRational test = {1, 1000};
...
}
but has problem when it is as below:
{
...
AVRational test = (AVRational){1, 1000};
...
}
gave errors:
1>..\..\..\projects\test\xyz.cpp(1139) : error C2059: syntax error : '{'
1>..\..\..\projects\test\xyz.cpp(1139) : error C2143: syntax error : missing ';' before '{'
1>..\..\..\projects\test\xyz.cpp(1139) : error C2143: syntax error : missing ';' before '}'
where AVRational (ffmpeg.org library) is defined as:
typedef struct AVRational{
int num; ///< numerator
int den; ///< denominator
} AVRational;
FFmpeg come with some pre-define value such as
#define AV_TIME_BASE_Q (AVRational){1, AV_TIME_BASE}
which is used as below
av_rescale_q(seek_target, AV_TIME_BASE_Q, pFormatCtx->streams[stream_index]->time_base);
will failed to compile on Visual C++ express 2008
It seem like the same code will be compiled with no error/warning on gcc compiler. Why I get this error on VC++? Is it a C/C++ standard way to do casting on struct value? Anyway I can avoid this error while still able to use the defined AV_TIME_BASE_Q?
Use av_get_time_base_q() instead of AV_TIME_BASE_Q for C++ or VS.
This was fixed in a patch
VC++ 2013 does not allow compound literals in C++ but it allows them in C. Options:
Rename your program with a .c suffix
Switch on the /TC flag for the program that does not compile.
The other alternative if you wish to keep to C++ is to change the declaration of AV_TIME_BASE_Q in the header file
static const AVRational AV_TIME_BASE_Q = {1, AV_TIME_BASE};
Then it will be using the constant instead of the compound literal.
For compound-literals errors in C++
wrong:
this->buffer.enqueue((tone_t) { duration, frequency });
correct:
tone_t tone = { duration, frequency };
this->buffer.enqueue(tone);

error C2143: syntax error : missing ',' before ':'

I'm trying to build am opensource game but keep getting this error when trying to build. I have been searching for the last half hour with nothing working here's the code the errors pointing to
void duel::restore_assumes() {
for(auto pcard : assumes)
pcard->assume_type = 0;
assumes.clear();
}
and the error is
Error 1 error C2143: syntax error : missing ',' before
':' c:\users\user\desktop\project source\ocgcore\duel.cpp 108 1 ocgcore
(Visual Studio 2010)
MS VC++ 2010 does not support the range based for statement that was introduced in the C++ 2011. However it has its own language extension: for each.
Try to change this code
void duel::restore_assumes() {
for(auto pcard : assumes)
pcard->assume_type = 0;
assumes.clear();
}
to
void duel::restore_assumes() {
for each (auto pcard in assumes)
pcard->assume_type = 0;
assumes.clear();
}
Otherwise you can use an ordinary loop with iterators of object assumes or some standard algorithm as for example std::for_each
As shown in this table : C++11 Compiler Support
Range-based for Loops aren't available with MSVC2010, but with MSVC2012 (which is version 11).
So if you use the 2010 compiler, this code won't compile.
The error message makes it pretty obvious: the compiler is not expecting a : in the for statement.

Why does MSVC++11 rejects constexpr qualification of a function?

So, playing around with constexpr, MSVC (Visual Studio 2012) gave me an error while trying to qualify my function with the constexpr keyword using this simple program (includes omitted):
constexpr int factorial(int n)
{
return n <= 1 ? 1 : (n * factorial(n-1));
}
int main(void)
{
const int fact_three = factorial(3);
std::cout << fact_three << std::endl;
return 0;
}
constexpr was underlined red with the following message:
Error : this declaration has no storage class or type specifier
and trying to compile the program gave the following output:
1>main.cpp(5): error C2144: syntax error : 'int' should be preceded by ';'
1>main.cpp(5): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
It really puzzles me as it is the very example that Cppreference uses to illustrate the use of constexpr. At first I used a simple function that returned a literal, i.e. constexpr int func(){return 5;}, but which yielded the same error. I interpreted the first message as "it should be a member function of a struct or class", but the example from Cppreference shows that it's not necessary apparently.
So, what am I obviously missing here ?
Quite simply - because Visual Studio doesn't support constexpr (prior to Visual Studio 2015).
Note that MSVC++11 is Visual Studio 2012; VC++10 is Visual Studio 2010.

C++11 compiler error when using decltype(var) followed by internal type of "var"

I'm using Visual C++ 2010, and here's my code snippet:
std::set<int> s;
decltype(s)::value_type param = 0;
I got the following error message, anyone can help me?
> error C2039: 'value_type' : is not a member of '`global namespace''
> error C2146: syntax error : missing ';' before identifier 'param'
This is a Visual Studio bug that was raised last year on Connect. It is issue 757545 ("Cannot use decltype before scope operator").
The issue has a workaround listed alongside it that is effectively the same as #iammillind's, except it uses std::identity that was removed from <functional> shortly prior to the publication of C++11, for whatever reason. (std::common_type with one template parameter is equivalent; std::remove_reference is the same in some cases.)
I see that with g++ 4.7.2 version, the code compiles fine. So it could be a compiler bug in MSVS.
For time being you can try below trick:
#ifdef COMPILER_BUG_STILL_THERE
template<typename T> struct Get { typedef T type; };
#define DECLTYPE(VAR) Get<decltype(VAR)>::type
#else
#define DECLTYPE(VAR) decltype(VAR)
#endif
Use it as:
DECLTYPE(s)::value_type param = 0;
Disclaimer: Ofcourse with this trick, you may have to use typename when inside templates. For that you can have 1 more macro such as #define TDECLTYPE(VAR) typename DECLTYPE(VAR)

member hook implementation for splay_multiset in Boost::Intrusive

I was implementing boost::intrusive for one of my project on visual C++ 2008 and i stumbled upon a problem. i am using splay hooks for splay_multiset containers. I have defined splay hook publically under MyClass (code below).
#include <boost/intrusive/unordered_set.hpp>
#include <boost/intrusive/splay_set.hpp>
#include <iostream>
using namespace boost::intrusive;
class MyClass
{
int int_;
public:
MyClass(int i)
: int_(i)
{}
splay_set_member_hook<link_mode<normal_link> > memberSplayHook;
//**OPTION-1**
//PROBLEM CODE SEGMENT ++
//typedef member_hook<MyClass, splay_set_member_hook<link_mode<normal_link> >, &MyClass::memberSplayHook> MemberOption;
//typedef splay_multiset<MyClass, MemberOption> MemberMultiSet;
//PROBLEM CODE SEGMENT --
MemberMultiSet mmset;
};
//**OPTION-2**
//WORKING CODE SEGMENT ++
typedef member_hook<MyClass, splay_set_member_hook<link_mode<normal_link> >, &MyClass::memberSplayHook> MemberOption;
typedef splay_multiset<MyClass, MemberOption> MemberMultiSet;
//WORKING CODE SEGMENT --
int main()
{
return 0;
}
The problem is, to use splay_multiset, whatever option i choose (either option-1 or 2, mention in code), in both cases i see compilation errors.
When Option-1 is enabled (option-2 is commented), i see errors below:
1>d:\projects\sampleproject\sample.cpp(21) : error C2327: 'MyClass::memberSplayHook' : is not a type name, static, or enumerator
1>d:\projects\sampleproject\sample.cpp(21) : error C2065: 'memberSplayHook' : undeclared identifier
1>d:\projects\sampleproject\sample.cpp(22) : error C3203: 'member_hook' : unspecialized class template can't be used as a template argument for template parameter 'O1', expected a real type
While, when Option-2 is enabled (option-1 is commented out), i dont see undeclared identifier error msg as these errors coming with option-1. But i do see errors like below (which are obvious).
1>d:\projects\sampleproject\sample.cpp(25) : error C2146: syntax error : missing ';' before identifier 'mmset'
1>d:\projects\sampleproject\sample.cpp(25) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
My question is why i am getting error in first case? What can i do to get pass this issue?
Boost member hooks have (always?) been broken, since they don't compile with Visual C++.
I don't have a VS at hand to check for the precise error message so I might be wrong (but reading 'member hooks' and 'Visual C++' always triggers 'there's a problem'-mode), but do try to check this:
http://permalink.gmane.org/gmane.comp.lib.boost.user/56875
EDIT: Don't take the headline literally -- the same applies to Visual C++ 2010 and 2012. All my member hooks use this workaround; at some point I might even try to understand what it does, or more importantly, how to package it into a more comfortable setup for less "I need to find a previous implementation of this workaround so I can copy-and-modify it"...