In-class member initializer fails with VS 2013 - c++

I expected the following code to compile, but Visual Studio 2013 Update 2 gives me an error, while g++ 4.7 compiles it fine.
using std::vector;
using std::string;
struct Settings
{
vector<string> allowable = { "-t", "--type", "-v", "--verbosity" };
};
VS 2013 compile fails with:
'std::vector<std::string,std::allocator<_Ty>>::vector' : no overloaded function takes 4 arguments
If I change the member as follows then it compiles fine:
vector<string> allowable = vector<string> { "-t", "--type", "-v", "--verbosity" };
I've looked at the proposal linked from Bjarne's FAQ and I've looked at the MSDN page on completed C++11 features in VS 2013 but I'm still confused. Should it compile as is, or am I wrong and must specify the type twice?

The example that you showed is perfectly valid C++, however it doesn't work for VC++2013.
This is a known VC++2013 bug reported since 31/10/2013 and its status is still active.
However, you can surmount it by doing a work-around. As #ildjarn suggested, by simply putting an extra pair of curly braces you force initializer_list<> constructor of the std::vector to be evoked instead of its fill constructor, like the example below:
#include <string>
#include <vector>
#include <iostream>
struct Settings {
std::vector<std::string> allowable = {{"-t", "--type", "-v", "--verbosity"}};
};
int main() {
Settings s;
for (auto i : s.allowable) std::cout << i << " ";
std::cout << std::endl;
}

Related

JSON output differs between gcc and MSVC

The below code snippet is using nlohmann-json library.
However the output differs between MSVC and GCC compilers (both compiled using -std=c++14).
MSVC outputs:
{"test":[]}
gcc outputs:
{"test":[[]]}
Code snippet:
#include "nlohmann/json.hpp"
#include <iostream>
int main() {
nlohmann::json output;
output["test"] = { nlohmann::json::array() };
std::cout << output.dump() << std::endl;
return 0;
}
The line output["test"] = { nlohmann::json::array() }; is triggering the difference in behavior. Removing the curly brackets around nlohmann::json::array() will align the behavior and always output {"test":[]}.
It seems the initializer list { json::array() } is interpreted by GCC as: json::array({ json::array() }) for some reason.
Could this be a potential bug in the json library, in GCC/MSVC or is there another explanation?
The nlohmann library has an already known issue with brace initialization and different compilers.
They mention this issue in the FAQ.
The workaround the library authors propose is to avoid brace initialization.

When debugging C++ code using Visual Studio Code, is it possible to automatically step over standard includes

Environment: Using Visual Studio Code with the Standard Microsoft C++ Debugging Extension. Using gdb as the underlying debugger.
For example: on the code below a step in on the commented line will jump to the standard string header.
Is there a way to avoid this?
#include <string>
#include <iostream>
int main()
{
std::string a = "Example String"; /// < Step IN here
std::cout << a << std::endl;
}
A more realistic example of why this is a problem:
In the case below I want to debug the a->methodToDebug()
but step in will send you to the source for the std::unique_ptr get method. You can still keep stepping in to get to your own code, but in more complicated code it becomes a pain.
#include <memory>
class A
{
public:
int methodToDebug() {
return -1 ;
}
};
int main()
{
auto a = std::make_unique<A>();
auto s = a->methodToDebug(); // <<-- Step in here, goes to get().
}
Turn on: Tools > Options > Debugging > General > [ ] Enable Just My Code.
It appears I can do this for recent versions of gdb(7.12.1 or higher) with the following in the .gdbinit file
skip -gfi /usr/include/c++/*/*/*
skip -gfi /usr/include/c++/*/*
skip -gfi /usr/include/c++/*

C3536 cannot be used before it is initialized

I am working on an old source code project which originally was written using MSVC 2008 and Boost 1.42, today I'm trying to port this to MSVC 2017 with Boost 1.73
There are many issues to resolve, one of which is below:
Severity Code Description Project File Line Suppression State
Error C3536 'binding': cannot be used before it is initialized Process Control Service Group processscope.cpp 197
The line that this occurs on:
auto binding = boost::bind(&IProcessChangeObserver::notify, _1, m_scope, change);
std::for_each(observers.begin(), observers.end(), binding);
Originally the assignment to binding was inline as the third parameter, it gives the same error. I can see why this is a problem, I cannot see why it ever worked?
Is there another way to write the above without the triggering a warning?
I've tried replacing with a standard loop:
for( std::list<boost::intrusive_ptr<IProcessChangeObserver> >::iterator itProc=objservers.begin();
itProc!=objservers.end(); itProc++ ) {
boost:bind(&IProcessChangeObserver::notify, itProc, m_scope, change);
}
To be honest I'm not 100% sure if this is a like for like replacement?
I have a suspicion the real problem is with binding which is likely not correctly initialized. There's bound to be more compiler messages about that.
It could be because Boost Bind stopped putting the _1 placeholders in the global namespace by default. You might detect this by adding -DBOOST_BIND_GLOBAL_PLACEHOLDERS to the compiler flags. However, heed the advice from the code:
BOOST_PRAGMA_MESSAGE(
"The practice of declaring the Bind placeholders (_1, _2, ...) "
"in the global namespace is deprecated. Please use "
"<boost/bind/bind.hpp> + using namespace boost::placeholders, "
"or define BOOST_BIND_GLOBAL_PLACEHOLDERS to retain the current behavior."
)
Minimal repro
See if you can reproduce with this minimal reproducer (I can't but I don't have access to the requisite versions ofr MSVC/Boost):
Live ON Coliru - GCC
Live On Rextester - MSVC
#include <algorithm>
#include <iostream>
#include <list>
#include <boost/bind/bind.hpp>
using namespace boost::placeholders;
#include <boost/intrusive_ptr.hpp>
#include <boost/smart_ptr/intrusive_ref_counter.hpp>
struct Scope {};
struct Change {};
namespace MyLib {
struct IProcessChangeObserver
: boost::intrusive_ref_counter<IProcessChangeObserver>
{
virtual ~IProcessChangeObserver() = default;
virtual void notify(Scope, Change) = 0;
};
struct Obs1 : IProcessChangeObserver {
void notify(Scope, Change) override { std::cout << "Obs1\n"; }
};
struct Obs2 : IProcessChangeObserver {
void notify(Scope, Change) override { std::cout << "Obs2\n"; }
};
}
using ObserverPtr = boost::intrusive_ptr<MyLib::IProcessChangeObserver>;
int main() {
using namespace MyLib;
std::list<ObserverPtr> observers {
new Obs1(), new Obs2(), new Obs1(),
};
Scope m_scope;
Change change;
auto binding = boost::bind(&IProcessChangeObserver::notify, _1, m_scope, change);
std::for_each(observers.begin(), observers.end(), binding);
}
Prints
Obs1
Obs2
Obs1
The actual fix was just to change _1 to std::placeholders::_1

Why MSVC C++ requires a default constructor in struct needed when returning from async? [duplicate]

I am trying to compile the following code in Visual Studio 2017:
#include <future>
int main()
{
std::promise<std::reference_wrapper<int>> promise;
(void)promise;
}
However, I get the following error:
error C2512: 'std::reference_wrapper': no appropriate default constructor available
Whereas it compiles fine with GCC and Clang.
Is this is a definite bug in Visual Studio or is it a valid implementation of std::promise?
Looks like it is a known issue in MSVC's standard library implementation.
A simpler reproduction scenario:
#include <future>
struct NoDefaultCtor
{
NoDefaultCtor() = delete;
};
int main() {
std::promise<NoDefaultCtor> p;
return 0;
}
I suppose you do not need std::reference_wrapper<int>. There is the suitable overloaded template for std::promise available:
template<class R> class promise<R&>;
Therefore you can fix your code in Visual Studio 2017:
#include <future>
int main()
{
std::promise<int&> promise;
(void)promise;
}

Bug or not? Visual Studio 2013 preview std::vector initializer list with std::string

Finally they did it. MSVC12 compiler now allows uniform initialization. But I found, that it works differently than GNU GCC 4.8.1 with -std=C++11 flag.
Consider this code:
#include <vector>
#include <string>
#include <iostream>
struct Data
{
Data(const std::string& name, int x):
m_Name(name),
m_X(x)
{}
std::string m_Name;
int m_X;
};
std::vector<Data> datas =
{
Data("one", 1),
Data("two", 2),
Data("three", 3),
};
int main()
{
for(auto it = datas.begin(); it != datas.end(); ++it)
std::cout << it->m_Name << " " << it->m_X << "\n";
}
Result with GCC (as expected):
one 1
two 2
three 3
(ideone link)
Result with MSVC12:
1
2
3
like strings hasn't been initialized.
Questions:
Does my code snippet syntax is correct according to C++11 standard?
Does GCC behavior is standard or is it some kind of extension?
Does MSVC behavior is standard or is it a bug?
This may have been a bug in VS2013 Preview. The output of the binary generated by the current VS2013 RC is consistent with g++.