cannot convert argument 1 from 'int' to 'int &' - c++

I'm getting the next error and I cannot find the reason for it:
Error C2664 'void SumID<long>::operator ()<int>(G &)': cannot convert argument 1 from 'int' to 'int &'
Why is passing an int by reference problematic?
I have the next class:
template <class T>
class SumID {
private:
T sumid;
public:
SumID():sumid()
{
}
SumID(T s)
{
sumid = s;
}
T getSumID()
{
cout << "inside getSum";
return sumid;
}
template <class G>
void operator() (G& a)
{
sumid = sumid+ a;
}
};
my main :
SumID<long> s;
for (int i = 0; i < 5; i++)
s(5); // <-- error here

When use s(5); the argument, 5, is not an lvalue. Hence, it cannot be used when the argument type is G&.
You can resolve the problem using one or both of the following approaches.
Create a variable and use it in the call.
int x = 5;
s(x);
Change the argument type to just G, G&& or G const&.
template <class G>
void operator() (G a) // Or (G&& a) or (G const& a)
{
sumid = sumid+ a;
}

Related

How to static_cast a pointer to const member function?

Surprisingly (embarrassingly?) I cannot get the syntax of the static_const of a const member function right. In short (details below) if the member function is not marked const I use:
static_cast<std::vector<double> (mymodule::Foo::*)(const std::vector<double>&)>(&mymodule::Foo::bar)
but marking the member function Foo::bar(...) const the compiler does not know what to do:
error: address of overloaded function 'bar' cannot be static_cast to type 'std::vector<double> (mymodule::Foo::*)(const std::vector<double> &)'
Where should I put the function's constness?
Details
I'm trying to create Python binding for the following module:
namespace mymodule {
class Foo
{
public:
Foo() = default;
template <class T>
T bar(const T& a) const
{
T ret = a;
for (auto& i : ret) {
i *= 2.0;
}
return ret;
}
template <class T>
T bar(const T& a, double f) const
{
T ret = a;
for (auto& i : ret) {
i *= f;
}
return ret;
}
};
} // namespace mymodule
whereby I write the Python bindings with pybind11:
#include <pybind11/pybind11.h>
namespace py = pybind11;
PYBIND11_MODULE(example, m)
{
py::class_<mymodule::Foo>(m, "Foo")
.def(py::init<>())
.def("bar",
static_cast<std::vector<double> (mymodule::Foo::*)(const std::vector<double>&)>(&mymodule::Foo::bar),
py::arg("a"))
.def("bar",
static_cast<std::vector<double> (mymodule::Foo::*)(const std::vector<double>&, double)>(&mymodule::Foo::bar),
py::arg("a"),
py::arg("f"));
}
which fails to compile:
.../example.cpp:54:14: error: address of overloaded function 'bar' cannot be static_cast to type 'std::vector<double> (mymodule::Foo::*)(const std::vector<double> &)'
static_cast<std::vector<double> (mymodule::Foo::*)(const std::vector<double>&)>(&mymodule::Foo::bar),
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.../example.cpp:19:7: note: candidate function template
T bar(const T& a) const
^
.../example.cpp:29:7: note: candidate function template
T bar(const T& a, double f) const
^
.../example.cpp:58:14: error: address of overloaded function 'bar' cannot be static_cast to type 'std::vector<double> (mymodule::Foo::*)(const std::vector<double> &, double)'
static_cast<std::vector<double> (mymodule::Foo::*)(const std::vector<double>&, double)>(&mymodule::Foo::bar),
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.../example.cpp:19:7: note: candidate function template
T bar(const T& a) const
^
.../example.cpp:29:7: note: candidate function template
T bar(const T& a, double f) const
^
2 errors generated.
You should add const at last as:
static_cast<std::vector<double> (mymodule::Foo::*)(const std::vector<double>&) const>(&mymodule::Foo::bar),
// ^^^^^

Class object as template funciton argument

I have an issue with the templates and my knowledge about them is definitely limited.
So I have a class which should store some information:
class Q
{
int integer;
int fractional;
public:
constexpr Q(int i,int f) : integer(i),fractional(f) {}
int get_i() const {return this->integer;}
int get_f() const {return this->fractional;}
constexpr int get_w() {return this->integer + this->fractional;}
friend ostream& operator<<(ostream& os, const Q& q){ os << "Q" << q.integer << "." << q.fractional << " (w:" << q.integer + q.fractional << ")"; return os; }
};
Then I have my templated function. This is just an example but it show the point:
template <Q input_q, Q output_q,const unsigned int X_0_evaluated_bit> void calculate_stuff (const int max_iterations)
{
std::array<Q,input_q.get_w()> input_queue_q;
}
And at the end the main (I'm using the SystemC library) where I generate the constant object Q that I want to use in the function
int sc_main(int argc, char *argv[])
{
constexpr Q Q1_i = Q(1,10);
constexpr Q Q1_o = Q(0,11);
// Number of bits used to address the LUT for the initial value
const unsigned int X_0_evaluated_bit = 5;
// Number of iteration for the Newton-Raphson
const int max_iterations = 2;
calculate_stuff <Q1_i,Q1_o,X_0_evaluated_bit> (max_iterations);
return 0;
}
If I try to compile I get the following error message:
check_ac_one_over.cpp:31:13: error: ‘class Q’ is not a valid type for a template non-type parameter
template <Q input_q, Q output_q,const unsigned int X_0_evaluated_bit> void calculate_stuff (const int max_iterations)
^
check_ac_one_over.cpp:31:24: error: ‘class Q’ is not a valid type for a template non-type parameter
template <Q input_q, Q output_q,const unsigned int X_0_evaluated_bit> void calculate_stuff (const int max_iterations)
^
check_ac_one_over.cpp: In function ‘void calculate_stuff(int)’:
check_ac_one_over.cpp:33:31: error: template argument 2 is invalid
std::array<Q,input_q.get_w()> input_queue_q;
^
check_ac_one_over.cpp:33:46: error: invalid type in declaration before ‘;’ token
std::array<Q,input_q.get_w()> input_queue_q;
^
check_ac_one_over.cpp: In function ‘int sc_main(int, char**)’:
check_ac_one_over.cpp:102:64: error: no matching function for call to ‘calculate_stuff(const int&)’
calculate_stuff <Q1_i,Q1_o,X_0_evaluated_bit> (max_iterations);
^
check_ac_one_over.cpp:102:64: note: candidate is:
check_ac_one_over.cpp:31:76: note: template<<typeprefixerror>input_q, <typeprefixerror>output_q, unsigned int X_0_evaluated_bit> void calculate_stuff(int)
template <Q input_q, Q output_q,const unsigned int X_0_evaluated_bit> void calculate_stuff (const int max_iterations)
^
check_ac_one_over.cpp:31:76: note: template argument deduction/substitution failed:
check_ac_one_over.cpp:102:64: note: invalid template non-type parameter
calculate_stuff <Q1_i,Q1_o,X_0_evaluated_bit> (max_iterations);
^
check_ac_one_over.cpp:102:64: note: invalid template non-type parameter
make: *** [check_ac_one_over.o] Error 1
Now I'm not sure if what I'm trying to do is possible. Does anyone have some ideas how can I make it work ?
Cheers,
Stefano
Does anyone have some ideas how can I make it work ?
Not a great idea, I suppose, but...
The error message is clear:
‘class Q’ is not a valid type for a template non-type parameter
But, in your example, you don't use the full Q object: you use the value of input_q.get_w().
So I suppose that you can pass as template parameter not the full Q object but only the value returned by get_w() that is a int so is a valid as template non-type parameter.
Something (using only the first template parameter; no idea about the use of the other)
template <int input_dim>
void calculate_stuff (const int max_iterations)
{
std::array<Q, input_dim> input_queue_q;
}
that you can call (taking in count that Q1_i and get_w() are constexpr)
calculate_stuff<Q1_i.get_w()> (1);
But observe that
1) get_w() should be also const, not only constexpr
constexpr int get_w() const {return this->integer + this->fractional;}
because a constexpr method isn't automatically const (starting from C++14) but a constexpr object is also const (so can't use get_w() if it isn't defined const)
2) If you want an array of Q as follows
std::array<Q, input_dim> input_queue_q;
the Q type require a constructor without parameters; by example adding default values to your constructor
constexpr Q(int i = 0, int f = 0) : integer(i),fractional(f) {}
I've found a solution. It's not the perfect one but it's quite close. Instead to use the object I'm using the pointer to the object which has become a global variable:
class Q
{
int integer;
int fractional;
public:
constexpr Q(int i = 0,int f = 0) : integer(i),fractional(f) {}
constexpr int get_i() const {return this->integer;}
constexpr int get_f() const {return this->fractional;}
constexpr int get_w() const {return this->integer + this->fractional;}
friend ostream& operator<<(ostream& os, const Q& q){ os << "Q" << q.integer << "." << q.fractional << " (w:" << q.integer + q.fractional << ")"; return os; }
};
template <const Q *input_q,const Q *output_q,const unsigned int X_0_evaluated_bit> void calculate_stuff (const int max_iterations)
{
std::array<Q,input_q->get_w()> input_queue_q;
}
constexpr Q Q1_i = Q(1,10);
constexpr Q Q1_o = Q(0,11);
int sc_main(int argc, char *argv[])
{
// Number of bits used to address the LUT for the initial value
const unsigned int X_0_evaluated_bit = 5;
// Number of iteration for the Newton-Raphson
const int max_iterations = 2;
calculate_stuff <&Q1_i,&Q1_o,X_0_evaluated_bit> (max_iterations);
return 0;
}
Cheers.

alias for multi parameter function template

I am trying to create a template for a multi-parameter function, and then an alias for a particular instantiation. From this really good post:
C++11: How to alias a function?
I found example code that works for a single function parameter and single template parameter:
#include <iostream>
namespace Bar
{
void test()
{
std::cout << "Test\n";
}
template<typename T>
void test2(T const& a)
{
std::cout << "Test: " << a << std::endl;
}
}
void (&alias)() = Bar::test;
void (&a2)(int const&) = Bar::test2<int>;
int main()
{
Bar::test();
alias();
a2(3);
}
When I try to expand to two function parameters as such:
void noBarTest(T const& a, T const& b)
{
std::cout << "noBarTest: " << a << std::endl;
}
void(&hh)(int const&, int const&) = noBarTest<int, int>;
I get these errors in Visual Studio:
error C2440: 'initializing' : cannot convert from 'void (__cdecl
*)(const T &,const T &)' to 'void (__cdecl &)(const int &,const int &)'
IntelliSense: a reference of type "void (&)(const int &, const int &)"
(not const-qualified) cannot be initialized with a value of type
""
I thought I followed the pattern exactly in expanding to 2 arguments.
What's the proper syntax for this?
template <typename T>
void noBarTest(T const& a, T const& b)
{
}
void(&hh)(int const&, int const&) = noBarTest<int>; // Only once
int main() {
return 0;
}
The type parameter int needs to be specified only once in noBarTest<int>.

error: invalid conversion from 'int' to 'const char*'

I'm realising a stack data structure. When I call pop function in main function, an error appeared. It phrases like this:
stack.h:13: error: invalid conversion from 'int' to 'const char*'
stack.h:13: error: initializing argument 1 of 'int remove(const char*)
'
And the problem is that I didn't write the remove function with a char or a char* type parameter.
So I hope any of you can help me out of here. Thanks for the help!
template <typename T>
class Stack : public Vector<T> {
public:
Stack () { Vector<T>(); }
T pop() { return remove( this->size() - 1 ); } //stack.h:13
};
template <typename T>
class Vector {
protected:
int _size;
int _capacity;
T* _elem;
void shrink();
public:
T remove ( int r );
int remove ( int lo, int hi );
};
template <typename T>
int Vector<T>::remove ( int lo, int hi ) {
if(lo==hi) return 0;
while( hi < _size ) _elem[ lo++ ] = _elem[ hi++ ];
_size = lo;
shrink();
return hi-lo;
}
template <typename T>
T Vector<T>::remove ( int r ) {
T e = _elem[r];
remove ( r, r + 1 );
return e;
}
in main function,
Stack<int> S;
for(i = 0; i<n; i++) {
S.push(i+1);
}
S.pop();
Since the base class Vector<T> depends on the template parameter, and so has a type that isn't known until the template is instantiated, unqualified name lookup doesn't look there. This means that your unqualified call to remove doesn't resolve to the base-class member, but to some other overload (probably this one).
Write this->remove or Vector<T>::remove to indicate that you're referring to a member.

Sorting an array with own template compare function in C++

template <class T>
bool cmp(const T &a, const T &b){
return a <= b;
}
template <class T>
void bubble_sort(T tablica[], int size, bool compare(T,T)){
bool change = true;
while(change){
change = false;
for(int i=0; i < size-1; ++i){
if(compare(tablica[i+1], tablica[i])){
zamien(tablica[i+1], tablica[i]);
change = true;
}
}
}
}
It doesn't work, I have errors:
'void bubble_sort(T [],int,bool (__cdecl *)(T,T))' :
could not deduce template argument for 'T []' from 'int [10]'
'void bubble_sort(T [],int,bool (__cdecl *)(T,T))' :
cannot use function template 'bool cmp(const T,const T)' as a function argument'
but when I replace a cmp function with that:
bool cmp(const int a, const int b){
return a <= b;
}
Everything works fine.
How to change my cmp function to work with templates?
The problem is that the "compare" function parameter that bubble_sort expects is of type:
bool compare(T,T)
While the "cmp" function is of type:
bool compare(const T&,const T&)
In order to fix it, modify the "compare" parameter's type:
template <class T>
void bubble_sort(T tablica[], int size, bool compare(const T&,const T&)){
/* ... */
}
This is how I handled with this problem:
int (*cmp_int)(int,int) = compare<int>;
bubble_sort(in, 5, cmp_int);
Now it should work fine in MS Visual.