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.
Related
I have a constexpr size_t array whose members will be passed to the template parameters of a class that gets initialized, iterating over the array to construct and use several differently templated objects. Here's the general idea:
template <size_t N>
class Foo
{
// magic
};
constexpr size_t c_arr[] = { 2, 5, 3, 2 };
for (int i = 0; i < 4; i++)
{
Foo<c_arr[i]> foo;
foo.bar();
}
However, this will raise the following error:
templ_arr.cpp: In function ‘int main()’:
templ_arr.cpp:56:21: error: the value of ‘i’ is not usable in a constant expression
Foo<c_arr[i]> foo;
^
templ_arr.cpp:51:14: note: ‘int i’ is not const
for (int i = 0; i < 3; i++)
^
templ_arr.cpp:56:20: note: in template argument for type ‘long unsigned int’
Foo<c_arr[i]> foo;
I can't seem to find a way to use const_cast on i to allow it to be used inside the parameter, nor can I do something like this to get around it, as it gives me the same error:
for (int i = 0; i < 4; i++)
{
const int j = i;
Foo<c_arr[j]> f;
foo.bar();
}
What am I doign wrong, and how can I get around this?
If you want values to be used as template parameter, use std::integer_sequence
template <size_t N>
class Foo
{
public:
void bar() {}
};
template<std::size_t ...I>
void foo_bar(std::index_sequence<I...>) {
int dummy[] = { (Foo<I>{}.bar(), 0) ... };
// ((Foo<I>{}.bar()), ...); if using C++17 or above
}
int main() {
constexpr std::index_sequence<2, 5, 3, 2> id;
foo_bar(id);
}
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;
}
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.
I'm writing C++ templates to evaluate expressions with variables. Basically, for a structure like (x+5)*(x-2) it will evaluate the whole expression for any variable x. Here's the relevant code:
.cpp file:
int main(int argc, const char * argv[]){
int x = 5;
typedef MULTIPLY <
ADD < VAR, LIT<5> >,
SUBSTRACT < VAR, LIT<2> >
>
EXPRESSION;
EXPRESSION e;
printf("(x+5)*(x-2) = %d for x=%d", e.eval(x), x);
return 0;
}
header file:
struct VAR{
static inline int eval(int i){ return i; };
};
template<int INT>
struct LIT{
static inline int eval(int i){ return INT; };
};
template<class L, class R>
struct ADD{
static inline int eval(int i){
return L::eval(i) + R::eval(i);
};
};
template<class L, class R>
struct SUBSTRACT{
static inline int eval(int i){
return L::eval(i) - R::eval(i);
};
};
template<class L, class R>
struct MULTIPLY{
static inline int eval(int i){
return L::eval(i) * R::eval(i);
};
};
Which when executed correctly prints out
(x+5)*(x-2) = 30 for x=5
Now, I'm trying to expand this code to accept an array of variables. So
int arr[2] = {1,2};
given to
(x+y)
should put the variables in order and calculate the same thing using the 2 (or any number of) separate values from the array (super simple example).
.cpp file:
int main(int argc, const char * argv[]){
int arr[2] = {1,2};
typedef ADD < VARS<2>, VARS<2> >
EXPRESSION;
EXPRESSION e;
printf("(x+y) = %d\n", e.eval(arr));
return 0;
}
and this is where I get stuck. This is what I have in the header file:
//take an array arr[] of size N
template<int N>
struct VARS{
static inline int eval(int arr[]){
//go for next value
VARS<N-1>::eval(arr+1);
//end return current one
return arr[0];
};
};
// if array size = 0, end execution
template<>
struct VARS<0>{
static inline int eval(int arr[]){ return 0; };
};
template<class L, class R>
struct ADD{
static inline int eval(int i){
return L::eval(i) + R::eval(i);
};
};
but when I try to compile it I get a bunch of errors:
ExpressionTemplate.cpp: In function 'int main(int, const char**)':
ExpressionTemplate.cpp:17:35: error: invalid conversion from 'int*' to 'int' [-fpermissive]
printf("(x+y) = %d\n", e.eval(arr));
^
In file included from ExpressionTemplate.cpp:5:0:
ExpressionTemplate.h:19:23: note: initializing argument 1 of 'static int ADD<L, R>::eval(int) [with L = VARS<2>; R = VARS<2>]'
static inline int eval(int i){
^
ExpressionTemplate.h: In instantiation of 'static int ADD<L, R>::eval(int) [with L = VARS<2>; R = VARS<2>]':
ExpressionTemplate.cpp:17:35: required from here
ExpressionTemplate.h:20:23: error: invalid conversion from 'int' to 'int*' [-fpermissive]
return L::eval(i) + R::eval(i);
^
ExpressionTemplate.h:6:23: note: initializing argument 1 of 'static int VARS<N>::eval(int*) [with int N = 2]'
static inline int eval(int arr[]){
^
ExpressionTemplate.h:20:36: error: invalid conversion from 'int' to 'int*' [-fpermissive]
return L::eval(i) + R::eval(i);
^
ExpressionTemplate.h:6:23: note: initializing argument 1 of 'static int VARS<N>::eval(int*) [with int N = 2]'
static inline int eval(int arr[]){
Any help will be most appreciated :)
Your code is passing an array of ints (which decays into an int*) into your ADD's eval function. But you defined ADD::eval to take a single int. You would need to add another function to ADD to account for the case when you pass an array in, or make a new class (ie. VAR_ADD) to handle this case.
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.