Armadillo initializer list is not working - c++

I am using the MSVC2013 64bit compiler under Windows 10.
According to:
std::cout << arma::arma_version::as_string() << std::endl;
I have version 6.100.1 (Midnight Blue) of the Armadillio library.
I have C++11 enabled, for example
auto il = { 10, 20, 30 };
for(auto ele : il)
cout<<ele<<endl;
is working. Also the library is correctly added, as the following code runs:
vec v;
v<<10<<20<<30;
cout<<v;
But trying to use initializer lists for Armadillio fails.
vec v = { 1.0, 2.0, 3.0 };
causes the compile error:
error: C2440: 'initializing' : cannot convert from 'initializer-list' to 'arma::Col'
No constructor could take the source type, or constructor overload resolution was ambiguous

In the folder armadillo-6.100.1\include\armadillo_bits
there is a config file called config.hpp.
There you find a paragraph saying:
#if !defined(ARMA_USE_CXX11)
// #define ARMA_USE_CXX11
//// Uncomment the above line to forcefully enable use of C++11 features (eg. initialiser lists).
//// Note that ARMA_USE_CXX11 is automatically enabled when a C++11 compiler is detected.
#endif
So it looks like the MSVC2013 64bit is not detected as a C++11 compiler from Armadillio. So uncommenting the line
// #define ARMA_USE_CXX11
Solved my problem. Now this is working like charm:
vec v = { 1.0, 2.0, 3.0 };
cout<<v;

The documentation says that vec is a typedef for Col<double:
For convenience the following typedefs have been defined:
vec = colvec = Col< double >
If we look on the Col constructors, we will find the following constructor that accepts an initializer list:
#if defined(ARMA_USE_CXX11)
template<typename eT>
inline
Col<eT>::Col(const std::initializer_list<eT>& list)
{
<...>
}
So my guess would be that ARMA_USE_CXX11 is not defined, and thus this constructor is not accessible.

Related

How to initialize a vector in c++ in visual studio code [duplicate]

This question already has answers here:
Visual Studio Code c++11 extension warning
(9 answers)
Visual Studio Code: code not running for C++11
(1 answer)
Closed 10 months ago.
I just set up visual studio code and made a very basic c++ program to test it:
#include <iostream>
#include <vector>
using namespace std;
int main() {
vector<int> vec = {1, 2, 3, 4, 5};
for (const auto &i : vec) {
cout << i << endl;
}
}
I'm not sure if I did anything wrong, but I get the following errors:
test.cpp:7:17: error: non-aggregate type 'vector<int>' cannot be initialized with an initializer list
vector<int> vec = {1, 2, 3, 4, 5};
^ ~~~~~~~~~~~~~~~
test.cpp:8:16: warning: 'auto' type specifier is a C++11 extension [-Wc++11-extensions]
for (const auto &i : vec) {
^
test.cpp:8:24: warning: range-based for loop is a C++11 extension [-Wc++11-extensions]
for (const auto &i : vec) {
^
2 warnings and 1 error generated.
In cpp standard, it says its using c++20. I'm not sure what compiler I'm using, because in settings it looks like it is using clang, but when it runs, the description says:
cd "/Users/(my name)/Dropbox/Mac/vsCodeProjects/c:c++/" && g++ test.cpp -o test && "/Users/(my name)/Dropbox/Mac/vsCodeProjects/c:c++/"test
Because it says g++ there I'm not sure if it using clang after all, but I can't check the version of g++ because when I do it returns the clang version. I've tried everything I've seen and fiddled a lot with the tasks.json and the cpp standard json but nothing works. Any help is appreciated.

C++ Protocol Buffer: Temporary of non-literal type 'google::protobuf::internal::CallOnInitializedMutex <std::mutex>' in a constant expression

I'm using the protoc-3.18.0-win32 version from here. After successfully compiling the .proto files, I get the following error in my QtCreator 5 (C++11) program:
C:\Users\MyName\MyProject\lib\include\google\protobuf\stubs\mutex.h:124: error: temporary of non-literal type 'google::protobuf::internal::CallOnceInitializedMutex<std::mutex>' in a constant expression
In file included from lib\include/google/protobuf/descriptor.h:66:0,
from lib\include/google/protobuf/message.h:121,
from lib\include/google/protobuf/generated_message_bases.h:42,
from src/protodata/myfile.pb.h:26,
from src/myfile/myfile.h:12,
from src\myclass/myclass.h:8,
from src\mywidget.cpp:2:
lib\include/google/protobuf/stubs/mutex.h: In constructor 'constexpr google::protobuf::internal::WrappedMutex::WrappedMutex()':
lib\include/google/protobuf/stubs/mutex.h:124:29: error: temporary of non-literal type 'google::protobuf::internal::CallOnceInitializedMutex<std::mutex>' in a constant expression
constexpr WrappedMutex() {}
^
lib\include/google/protobuf/stubs/mutex.h:98:7: note: 'google::protobuf::internal::CallOnceInitializedMutex<std::mutex>' is not literal because:
class CallOnceInitializedMutex {
^~~~~~~~~~~~~~~~~~~~~~~~
lib\include/google/protobuf/stubs/mutex.h:98:7: note: 'google::protobuf::internal::CallOnceInitializedMutex<std::mutex>' has a non-trivial destructor
where the erroneous lines of code are:
// Mutex is a natural type to wrap. As both google and other organization have
// specialized mutexes. gRPC also provides an injection mechanism for custom
// mutexes.
class GOOGLE_PROTOBUF_CAPABILITY("mutex") PROTOBUF_EXPORT WrappedMutex {
public:
#if defined(__QNX__)
constexpr WrappedMutex() = default;
#else
constexpr WrappedMutex() {} // <--- Error points here
#endif
I hit the same issue when trying to use protobuf version higher than 3.15.0 with gcc 7.3 and c++17. This turned out to be a gcc bug, see more in https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82461.
After looking into the protobuf generated code, what i find is in version after 3.15, protobuf generated code container pervasive 'constexpr' which trigger the gcc bug.
Possible solution:
use higher version of gcc, the bug is fixed in 7.4 (preferred)
use '-std=c++14' instead of '-std=c++17', this works for me
use protobuf older than 3.15, 3.13 and 3.14 works for me.
In my case it was enough:
Go to your opencv folder, find the file \opencv\sources\3rdparty\protobuf\src\google\protobuf\stubs\mutex.h and delete the line after the first else at the WrappedMutex class,
class GOOGLE_PROTOBUF_CAPABILITY("mutex") PROTOBUF_EXPORT WrappedMutex {
audience:
#if defined(__QNX__)
constexpr WrappedMutex() = default;
#else
constexpr WrappedMutex() {} // **Delete this line**
#endif

Unexpected error on declaring vector in c++

I'm getting an unexpectred error when I initialize a vector in the main.
I was expecting the following output:
0 1 2
I can't see why it's not working. I also writed the same code in another pc using the same compiler, and it works.
#include <iostream>
#include <vector>
using namespace std;
int main()
{
vector<int> vett = {0,1,2};
for (int i : vett) {
cout << i << " ";
}
return 0;
}
error: could not convert '{0, 1, 2}' from '<brace-enclosed initializer list>' to 'std::vector<int>'|
You need to compile with at least C++11. List initialization came with C++11.
-std=c++11
You are compiling with something older than C++11, it does not support initializer list constructor.
If you are using Code::Blocks follow these steps:
Settings -> compiler -> compiler flags -> select C++11 or above

C++11 support in Emscripten

I would like to compile a C++ code using Emscripten, where I use some C++11 features. Unfortunately I get an error:
index.cpp:13:18: error: expected expression
vv.push_back({1.5f, 2.f});
^
index.cpp:14:18: error: expected expression
vv.push_back({5.f, 0});
^
index.cpp:15:18: error: expected expression
vv.push_back({1, 1});
^
index.cpp:17:9: warning: 'auto' type specifier is a C++11 extension [-Wc++11-extensions]
for(auto& item : vv) {
^
index.cpp:17:20: warning: range-based for loop is a C++11 extension [-Wc++11-extensions]
for(auto& item : vv) {
I can't understand, why I get this errors. The newest Emscripten and Clang versions are activated using emsdk.
The code is:
#include<iostream>
#include<vector>
struct AA {
float a;
float b;
};
int main() {
std::vector<AA> vv;
vv.push_back({1.5f, 2.f});
vv.push_back({5.f, 0});
vv.push_back({1, 1});
for(auto& item : vv) {
std::cout << item.a << ' ' << item.b << std::endl;
}
}
I even get a message: LLVM version appears incorrect (seeing "4.0", expected "3.7")
If it is true, it should wotk, because "Clang 3.3 and later implement all of the ISO C++ 2011 standard."
Suggestion: add -std=c++11 to your compiler options.
-Wc++11-extensions is a flag to add warnings, not to add C++11 support.

Using auto in loop error "auto must have an initializer"

I want to use the auto keyword but get this error when compiling (Visual C++ Express 2010)
typedef std::list<int> MyList;
int main()
{
const int args[] = {0, 1, 2};
MyList myList(std::begin(args), std::end(args));
for(auto& value : myList)
{
std::cout << value << std::endl;
}
}
Output:
error C2143: syntax error : missing ',' before ':'
error C2530: 'value' : references must be initialized
error C3531: 'value': a symbol whose type contains 'auto' must have an initializer
The C++ compiler in VS2010 does support range-based for loops, but with a pre-standard syntax.
(And seriously, you can't expect a compiler finished about 2 years before the Standard to be fully compliant)
for each (int& value in myList)
{
std::cout << value << std::endl;
}
There are two issues in your code:
You need to explicitly include the headers for the functionality you use.
#include <list>
#include <iostream>
VS2010 does not support C++11 range-based "for" loops. The feature was implemented much later. See the following table: http://msdn.microsoft.com/en-us/library/hh567368.aspx