how do i iterate the pair array arguments passed as a pointer ?
i had tried to use as reference pair &arr . but it doesnt worked either . can i pass pair<lli,lli> a[n]; as reference ??
#pragma GCC optimize ("O3")
#pragma GCC target ("sse4")
#define LOCAL
#include <bits/stdc++.h>
using namespace std;
#define ff first
#define ss second
typedef long long int lli;
typedef unsigned long long int ulli;
void yeah( pair<lli,lli> *arr ){
// cout << arr[0].ff; 100
//this doesnt work :(
for(auto e : arr){
cout << e.ff << " " << e.ss << endl;
}
}
int main() {
int n = 10;
pair<lli,lli> a[n];
a[0].ff = 100;
a[1].ss = 150;
yeah(a);
}
this is the error im getting
prog.cpp: In function 'void yeah(std::pair)':
prog.cpp:13:18: error: no matching function for call to 'begin(std::pair&)'
for(auto e : arr){
^
^
A possible solution with fixed-size arrays:
template<std::size_t size>
void foo(std::pair<int, int> (&arr)[size]) {
for (auto e : arr) {
...
}
}
constexpr std::size_t n = 10; // should be known at compile time
std::pair<int, int> a[n];
foo(a);
I would recommend ditching the VLA (which is not part of C++ anyway) and use std::vector instead. Include <vector> and change the declaration to this:
std::vector<std::pair<lli, lli>> a(n);
And the function's signature to:
void yeah(std::vector<std::pair<lli, lli>> &arr)
Related
This question already has answers here:
Range based for-loop on array passed to non-main function
(3 answers)
Closed 3 years ago.
I am trying to print values of array in called function using foreach loop but facing compilation error. Using c++11 compiler in linux platform and using VIM editor.
Tried using C-style for loop and it worked, when the size is passed from calling function
#include <iostream>
using namespace std;
void call(int [], int);
int main()
{
int arr[] = {1,2,3,4,5};
int size = sizeof(arr)/sizeof(arr[0]);
call(arr,size);
}
void call(int a[],int size)
{
for(int i =0 ; i<size; i++)
cout << a[i];
}
For-each loop used in the below code, which fails to compile.
#include <iostream>
using namespace std;
void call(int []);
int main()
{
int arr[] = {1,2,3,4,5};
call(arr);
}
void call(int a[])
{
for ( int x : a )
cout << x << endl;
}
For-each loop in C++11 expects to know the size of array to iterate ? If so, how it will be helpful with respect to traditional for loop. Or something wrong i coded here?
I would look forward for your help. Thanks in advance.
Because int a[] as function parameter is not an array, it is the same as writing int *a.
You can pass the array by reference to make it work:
template <size_t N> void call(int (&a)[N])
working example: https://ideone.com/ZlEMHC
template <size_t N> void call(int (&a)[N])
{
for ( int x : a )
cout << x << endl;
}
int main()
{
int arr[] = {1,2,3,4,5};
call(arr);
}
Basically ,I want hash table with link list which stores 3 int type variable so I am using unordered multimap with int and tuple .But its giving me compile time error WHERE I AM DOING WRONG .And is there any other efficient way of doing this . And further i want to find min on imposing some conditions on b and c in all the list contained in the buckets.For this I am thinking to use stl min method of algorithms but I am not able to figure out how to send second and third data of tuple as an argument for lambda function.
#include <iostream>
#include <iterator>
#include <bits/stdc++.h>
#include <vector>
#include <tuple>
#include <algorithm>
#include <numeric>
using namespace std;
int main()
{
std::unordered_multimap<int, std::tuple<int, int, int>> um;
int t;
cin >> t;
while (t--)
{
int n, d;
cin>>n>>d;
for (int i = 0; i < n; ++i) {
int a, b, c;
cin >> a >> b >> c;
um.insert(make_pair(a, std::make_tuple(a, b, c)));
}
}
for (std::unordered_multimap<int, std::tuple<int, int, int>>::const_iterator i = um.begin(); i != um.end(); ++i) {
cout << i->second->get<1> << endl;
}
}
this the error when i am just trying to print values
main.cpp: In function 'int main()':
main.cpp:34:18: error: base operand of '->' has non-pointer type 'const std::tuple'
cout<second ->get<1><main.cpp:35:3: error: expected declaration before '}' token
}}
^
In
cout << i->second->get<1> << endl;
i is an iterator to a std::unordered_multimap<int, std::tuple<int, int, int>>. That means that i->second gives you the std::tuple<int, int, int> part of the key/value pair. Since it is not a pointer you do not use -> to access it's members but instead you use ..
That said get is not a member function of std::tuple. std::get is a global function and you pass the tuple to it to get its element. That would make you code look like
std::cout << std::get<1>(i->second) << std::endl;
#include <bits/stdc++.h>
using namespace std;
int* insertionSort(int* a);
int main()
{
int a[5];
for(int i=0;i<5;i++)
{
cin>>a[i];
}
int b[5];
*b = insertionSort(a);
for(int i=0;i<5;i++)
{
cout<<b[i]<<" ";
}
}
int* insertionSort(int* a)
{
for(int i=1;i<5;i++)
{
int key=a[i];
int j=i-1;
while(j>0 && a[j]>key)
{
a[j]=a[j+1];
j-=1;
}
a[j+1]=key;
}
return a;
}
So this is my code for insertion sort. But when I run this it gives me the error
insertionSort.cpp: In function ‘int main()’:
insertionSort.cpp:15:21: error: invalid conversion from ‘int*’ to ‘int’ [-fpermissive]
*b = insertionSort(a);
I would like to know how does passing and returning arrays in functions work in C++. What is the error in my code?
P.S : It may happen that my insertion code may be wrong. I have not really tested it so pardon me I could not check it because of this error. It would be really helpful if someone can explain it in detail.
insertionSort is returning a int pointer, and you're trying to assign it to an int by dereferencing the pointer (*b). The correct syntax would be
b = insertionSort(a);
Also, b should be declared as int* b
P.S., this compiles, but still doesn't work as intended, but that's a whole different question from the one you posed.
#include <array>
#include <algorithm> // sort
#include <iostream>
constexpr size_t size {5};
std::array<int, size>* insertionSort(std::array<int, size>& a)
{
std::sort(a.begin(), a.end());
return &a;
}
int main()
{
std::array<int, size> a {1, 4, 3, 2, 5};
std::array<int, size>* b = insertionSort(a);
for(size_t i = 0; i < size; ++i)
std::cout << (*b)[i] << std::endl;
}
You should use the standard library functions when possible (here the sort one)
Thanks to C++11 we know have array (instead of playing with raw pointers)
I am trying to learn how to use TBB, so I'm modifying a sample program I found that is designed to compute powers of an array of complex numbers. Originally, it was passing an array into the parallel_for loop, but I am trying to change it so that it passes in a vector. However, I cannot get my code to compile; I get the following error (compiled using g++ -g program_name.cpp -ltbb):
error: passing ‘const std::complex<double>’ as ‘this’ argument
discards qualifiers [-fpermissive] result[i] = z;
My code is below:
#include <cstdlib>
#include <cmath>
#include <complex>
#include <ctime>
#include <iostream>
#include <iomanip>
#include "tbb/tbb.h"
#include "tbb/blocked_range.h"
#include "tbb/parallel_for.h"
#include "tbb/parallel_for_each.h"
#include "tbb/task_scheduler_init.h"
using namespace std;
using namespace tbb;
typedef complex<double> dcmplx;
dcmplx random_dcmplx ( void )
{
double e = 2*M_PI*((double) rand())/RAND_MAX;
dcmplx c(cos(e),sin(e));
return c;
}
class ComputePowers
{
vector<dcmplx> c; // numbers on input
int d; // degree
vector<dcmplx> result; // output
public:
ComputePowers(vector<dcmplx> x, int deg, vector<dcmplx> y): c(x), d(deg), result(y) { }
void operator() ( const blocked_range<size_t>& r ) const
{
for(int i=r.begin(); i!=r.end(); ++i)
{
dcmplx z(1.0,0.0);
for(int j=0; j < d; j++) {
z = z*c[i];
};
result[i] = z;
}
}
};
int main ( int argc, char *argv[] )
{
int deg = 100;
int dim = 10;
vector<dcmplx> r;
for(int i=0; i<dim; i++)
r.push_back(random_dcmplx());
vector<dcmplx> s(dim);
task_scheduler_init init(task_scheduler_init::automatic);
parallel_for(blocked_range<size_t>(0,dim),
ComputePowers(r,deg,s));
for(int i=0; i<dim; i++)
cout << scientific << setprecision(4)
<< "x[" << i << "] = ( " << s[i].real()
<< " , " << s[i].imag() << ")\n";
return 0;
}
You're trying to modify non-mutable member field result in const-qualified operator().
Resolve this discrepancy.
Edit #1: I have already mentioned the two keywords above. Either:
Remove const qualifier from operator():
void operator() ( const blocked_range<size_t>& r ) { ... }
Make result mutable:
mutable vector<dcmplx> result;
Additional erorrs may emerge after applying (although strongly preferred) variant no. 1. No. 2 is just for completeness and is used only in marginal situations.
It indeed results in an error with the 1st variant. This is because tbb::parallel_for takes Func by const&, so it can call only const-qualified member functions on your functor. Why? TBB doesn't want to waste performance by copying large functors (STL passes them by value).
I don't know what's the common practice here, I've never used this library.
Edit #2: Probably all you were missing was that result wasn't a reference:
vector<dcmplx> &result;
Now you'll be able to modify it, even in const-qualified operator(). Modifying a member that gets destructed afterwards wouldn't make sense.
Don't forget to change the constructor's signature to pass y by reference, too.
Off topic issues in your code:
Not included <vector> header
using namespace bulky_namespace globally
not using size_t for i in the for-loop
maybe more...
I'm trying to call addValues below:
Obj *s = new Obj();
vector<tm> dates(SIZE);
vector<double> values[COUNT];
for (uint i = 0; i < COUNT; i++) {
values[i] = vector<double>(SIZE);
}
s->addValues(&dates, &values); // <- this is the error line
and I've defined addValues:
void addValues(vector<tm> *newDates, vector<double> (*newValues)[COUNT]);
The exact error is:
no matching function for call to ‘Stock::addValues(std::vector<tm, std::allocator<tm> >*, std::vector<double, std::allocator<double> > (*)[5])’
I think the idea is that my method signature does not match.
What is the correct signature for addValues?
template <size_t N>
void addValues(vector<tm>* newDates, vector<double> (&newValues)[N]);
The reason this works is because its a template. The value N is known at compile time since you define values as an array: vector<double> values[COUNT]. Since the compiler knows the size of values at compile time, it is able to replace N with COUNT.
Since it is a template you will be able to call this function with any size array, not necessarily COUNT size.
I would also recommend changing newDates to a reference, as Fred Nurk suggested.
template <size_t N>
void addValues(vector<tm>& newDates, vector<double> (&newValues)[N]);
This is how I rewrote your code to make it compile:
#include <ctime>
#include <vector>
using namespace std;
typedef unsigned int uint;
#define SIZE 3
#define COUNT 3
struct Obj {
void addValues(vector<tm> *newDates, vector<double> (*newValues)[COUNT])
{}
};
int main() {
Obj *s = new Obj();
vector<tm> dates(SIZE);
vector<double> values[COUNT];
for (uint i = 0; i < COUNT; i++) {
values[i] = vector<double>(SIZE);
}
s->addValues(&dates, &values);
}
and it compiles correctly.
As you see, the code is almost the same as yours. Try checking if the COUNT value used in the member function's declaration is the same as the one where you create values.