Hi I am working through some C++ issues and I'm not familiar with the language.
I am trying to initialize a std::pair, double> with this syntax:
std::pair<std::vector<int>, double> output = { {}, 0.0f };
gcc 5.4.0 on Ubuntu 16.04 generates this error:
no known conversion for argument 1 from ‘std::pair<std::vector<int>, double>’ to ‘std::initializer_list<int>
The same error happens if I use this syntax:
std::pair<std::vector<int>, double> output{{}, 0.0f };
What is the issue?
You are using an extended initializer list (std::initializer_list) which is available since C++11.
For the gcc 5.4.0 compiler, you need to compile it with C++11 flag:
$ g++ main.cpp -std=c++11
https://gcc.godbolt.org/z/SHzREE
Related
I have written the following code in which I have initialise the vector with along with declaration of vector. Just like array but it is throwing the following error :-
CODE IS :-
# include <iostream>
# include <vector>
using namespace std;
int main()
{
vector <int> v = {1,2,3,4,5};
vector <int> :: iterator it ;
it = v.begin();
cout<< (*it) <<endl;
return 0;
}
THE OUTPUT I RECEIVED IIN TERMINAL IS:-
apple#Apples-MacBook-Air Iterators % cd "/Users/apple/Desktop/CODE/Iterators/" && g++ iteratorsBasics.cpp -o iterat
orsBasics && "/Users/apple/Desktop/CODE/Iterators/"iteratorsBasics
iteratorsBasics.cpp:8:18: error: non-aggregate type 'vector<int>' cannot be initialized with an initializer list
vector <int> v = {1,2,3,4,5};
^ ~~~~~~~~~~~
1 error generated.
apple#Apples-MacBook-Air Iterators %
Being the beginner I don't know how to sort this out please help.
the c++ version I checked in terminal by sawing some videos over internet is as follows:-
Apple clang version 13.0.0 (clang-1300.0.29.30)
Target: arm64-apple-darwin21.3.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin
You are compiling agains C++98 or C++03 standard versions. Add the flag -std=c++11 (or later: c++14/c++17/c++20) to the compiler invocation and it should compile.
Before C++11 std::initializer_list and the std::initializer_list overload of the std::vector constructor did not exist.
Try compiling your code with the following compiler flag:
-std=c++11
So the command:
g++ -std=c++11 your_file.cpp
We just got burnt by a typo: "constexpr bool maxDistance=10000;"
Both gcc and clang compile this with no warning.
The real error here is that the variable shouldn't have been of type bool, but should have been an integer type instead.
How can we ensure we get a compiler warning in future?
#include <iostream>
constexpr bool number = 1234;
int main(int argc, char* argv[])
{
std::cout << number + 10000 << std::endl; // prints 10001.
return number;
}
The error here is that the variable is declared with the wrong type, however neither clang nor gcc give a warning.
gcc -Wall -std=c++14 test.cpp -lstdc++
clang -Wall -std=c++14 test.cpp -lstdc++
(using gcc 5.4.0 and clang 3.8.0)
Note: I've since learnt about a possible compile flag: -Wint-in-bool-context however this doesn't appear to be implemented in the version I'm using (5.4.0) nor in clang (3.8.0).
Is this the right way to go?
You should use direct list initialization syntax, it prohibits narrowing:
constexpr bool number{1234}; // error: narrowing conversion of '1234' from 'int' to 'bool' [-Wnarrowing]
I've discovered that gcc has a flag '-Wint-in-bool-context' however this doesn't appear to be implemented in the version I'm using (5.4.0) nor in clang (3.8.0).
Is this the right way to go?
My problem seems somewhat similar to Conversion from null-integer to pointer in comma list
Here is a minimal example
#include <utility>
struct Object {
double foo;
};
std::pair<Object*,int> test_function() {
typedef std::pair<Object*,int> pair_t;
return pair_t(NULL, 2);
}
// test.cc
With gcc 4.4.7, g++ -std=c++0x -c test.cc -o test.o fails with
/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../include/c++/4.4.7/bits/stl_pair.h:90: error: invalid conversion from \u2018long int\u2019 to \u2018Object*
It does compile if I omit -std=c++0x. Also, if I use newer versions of gcc, the compilation is fine. Is there anything wrong with the code? Should one expect such differences in gcc versions?
A later edit: I can also return pair_t((Object*)NULL, 2)
I believe the answer to your question is here:
C++ can't initialize a pointer in a pair to NULL
The NULL is represented as a long by gcc and it cannot be converted to type Object* without the explicit cast.
Consider the code below:
#include <tuple>
int main() {
std::tuple<char[2], int> t1;
std::tuple<int> t2;
decltype(std::tuple_cat(t1, t2)) t3;
}
It compiles fine with g++ (in version >= 5.2) and icc (13.0.1), but not in clang++ and older versions of g++ where it gives nasty error:
array initializer must be an initializer list or string literal
My hunch tells me that the code shouldn't compile and clang++ and older versions of g++ are actually right here, but want to take a second opinion.
I have written fairly simple code to check out unordered_pair
// unordered_map example
#include <iostream>
#include <unordered_map>
int main (){
std::unordered_map<double, double> mymap = {
{5,2.3},
{7,34},
{4,12}
};
std::cout<<":::: unordered_map ::::"<<std::endl;
std::cout<<"5 ->"<<mymap[5]<<std::endl;
std::cout<<"7 ->"<<mymap[7]<<std::endl;
std::cout<<"4 ->"<<mymap[4]<<std::endl;
std::cout<<"Done ! ";
return 0;
}
I get the following error
unordered_map.cpp:5:37: error: non-aggregate type 'std::unordered_map<double, double>' cannot be initialized with an initializer list
std::unordered_map<double, double> mymap = {
^ ~
1 error generated.
Compilation failed
I am working on OSX and using geany.
Build command in Geany is :
g++ -Wall -c "%f"
unordered_map was introduced in the C++11 standard. If your g++ version supports it, you can enable c++11 standard with option -std=c++11
is there a way to use associative containers in older standards
std::map is an associative container. It exists in all c++ standards.
I was trying to use unordered_map because it is faster than map
unordered_map is faster in some cases. map is faster in other cases. Don't assume one way until you have measured.
However, using map without -std=c++11 still gives me same error as above
That's because you use list initialization which also requires c++11.
The old way of initializing a map:
std::map<int, int> m;
m[1] = 3;
m[2] = 2;
m[3] = 1;
Boost has a neat template for similar syntax to list initialization:
map<int,int> next = map_list_of(1,2)(2,3)(3,4)(4,5)(5,6);