I have this code
template <class N>
inline N swap(N a, N b) {
int c = *a;
*a = *b;
*b = c;
}
with this function I get this error: error: 'N' does not name a type
Error compiling.
This is my normal function.
inline void swap(int *a, int *b) {
int c = *a;
*a = *b;
*b = c;
}
My problem is that I need to use this function with unsigned and normal ints.
Is it possible to do this with templates.
I think you want something like this:
template<typename T>
inline void swap(T* a, T* b) // Use T* if you're expecting pointers
^^^^ // Notice the return type
{
T c = *a;
*a = *b;
*b = c;
}
Change declaration of the pointer from int c to N* c because it may take another data type as parameter , in addition to that you can't put a value of a pointer in a normal variable .
Related
I had this struct the other day:
struct foo_t {
char a, b, c;
} *foo = (foo_t*)untyped_memory;
…but having a named type for it was excessive. However, its unnamed form:
struct {
char a, b, c;
} *bar = untyped_memory;
...did not compile because of pointer types being incompatible.
Is there any way to make it work?
If you have access to C++11 or above then you can use decltype i.e.
struct {
char a, b, c;
} *bar = (decltype(bar))untyped_memory;
Is it possible to define a custom converter (converter1<T> and converter2) between different types of raw pointer A* and B*,
then make all functions (fa() and fb()) in a certain class
use an appropriate converter (converter1<T> or converter2)?
In short, I want the program to convert A* to B* and vice versa USING my custom functions.
I wish it would do that automatically for my convenience.
class Manager{
void fb(B* b){ /** something complex */ }
void fa(A* a){ /** different thing complex */ }
void testCase(){
A* a= ... ;
fa(a);
fb(a); //automatic convert to B* using "converter2" (wish)
B* b= ... ;
fa(b); //automatic convert to A* using "converter1" (wish)
fb(b);
}
template<class T> T* converter1(B* b){ //hardcoded, non-static.
return this->getId<T>(b);
//^^^ just an example to show how custom it is,
// currently T=A
}
B* converter2(A* a){ //hardcoded
return a->getB();
//^^^ just an example to show how custom it is.
}
}
The real case has many A - A1, A2, A3 and so on.
A and B are not derived from each other.
I wish there is a way. I think about constructor of pointer.
No this is not possible.
Pointers are built-in types and only built-in conversions between built-in types exist. User-defined conversions only work for user-defined class types.
You may want to switch to your own brand of smart pointers to handle this.
through references (or smart pointers) it's more possible:
struct A {};
struct B {};
A& convert_to_a(A& a) { return a; }
A convert_to_a(B const& b) {
// makes a new A from a B
return A();
}
B& convert_to_b(B& b) { return b; }
B convert_to_b(A const& a) { return B(); }
struct Manager
{
template<class T>
void fa(T&& t) {
auto&& a = convert_to_a(t);
// do something with a
(void)a;
}
template<class T>
void fb(T&& t) {
auto&& b = convert_to_b(t);
// do something with b
(void)b;
}
};
int main()
{
A a;
B b;
Manager m;
m.fa(a);
m.fb(a);
m.fa(b);
m.fb(b);
}
It is not possible the way you want it.
Anyway, you can use a catch-all function and a bunch of traits to simulate it.
It follows a minimal, working example:
#include<iostream>
struct A {};
struct B {};
template<typename T>
A* ToAConverter(T*) = delete;
template<>
A* ToAConverter<B>(B *b) {
// just an example
return new A;
}
struct Manager{
void fa(A* a){ std::cout << "fa" << std::endl; }
template<typename T>
void fa(T *t) {
std::cout << "convert and forward" << std::endl;
fa(ToAConverter<T>(t));
}
void testCase(){
A *a = new A;
fa(a);
B *b = new B;
fa(b);
}
};
int main() {
Manager m;
m.testCase();
}
In case you haven't defined a converter for a specific type, you'll receive a compile-time error.
As you can see, you have no longer to call explicitly the converter when you invoke fa.
For example, I have the following codes:
int a = 1;
int b = 2;
int *c = &a;
int &d = *c;
c = &b;
d++;
What is behaviour of line 4? If i want a reference to a pointer,is it correct to use
int *&e = c;
Is there any reason why to choose a reference to a pointer?
This declaration
int &d = *c;
declares a reference that refers the object pointed to by pointer c.
When this declaration was executed pointer c pointed to object a
int *c = &a;
So the referecne d refers object a. References may not be reassigned. They shall be initialized when they are declared.
Thus the expression in statement
d++;
increases object a.
You may declare a reference to a pointer.
This declaration
int *&e = c;
is valid.
Constant references can be bound to a temporary object. You may not take an address of a temporary object. Refrences alow to use more simple expressions.
Consider for example a simplified function swap that swaps two integers.
Using pointers the function would look like
void swap( int *a, int *b )
{
int tmp = *a;
*a = *b;
*b = tmp;
}
and it could be called like
int a = 5;
int b = 10;
swap( &a, &b );
Using references you could write the function the following way
void swap( int &a, int &b )
{
int tmp = a;
a = b;
b = tmp;
}
and its call would look simpler than the call of the function with pointers.
int a = 5;
int b = 10;
swap( a, b );
regarding the meaning of line 4
int a = 1;
int*c = &a; // okay: pointer to int, points to a
int&d = *c; // okay; reference to int, refers to *c=a;
A reference to a pointer is useful as argument to a function that may alter its value (=address pointed to), for example
void allocate(int*&p)
{ p=new int[10]; }
The following code is one that I written for myself in order to test how pointers and vectors work.
I am very new to C++.
#include <vector>
#include <iostream>
using namespace std;
int main(void)
{
//Create the integer pointer vector, and clean it to initialize
vector<int *> lol;
lol.clear();
//Create the pointers and point them to 1,2,3
int a1=1, a2=2, a3=3;
int* a, b, c;
a=&a1;
b=&a2;
c=&a3;
//Put the pointers into the vector
lol.push_back(a);
lol.push_back(b);
lol.push_back(c);
//Return the value of the middle pointer
cout << *lol[1];
}
I get a whole wall of errors while compiling.
Can anyone help? Bear in mind I can only understand novice.
The problem is with this line:
int* a, b, c;
a is int*, but b and c are just ints.
int *a, *b, *c;
Would make it all int*s.
int* a;
int* b
int* c;
does the same thing, but with clearer intentions of declaring three int*s.
See: Placement of the asterisk in pointer declarations
UPDATE: Even better:
int* a = &a1;
int* b = &a2;
int* c = &a3;
Whenever you can, don't separate variable initialization and its declaration.
When declaring multiple pointers on one line, you have to specify the * symbol in front of each pointer variable.
int * a, b, c;
should be :
int *a, *b, *c;
The line :
int * a, b, c;
is interpreted as :
int *a;
int b;
int c;
If you declare variables, do not declare multiple variables on the same line.
What you thought you did was to declare three pointers to int. What you did, was to declare three ints, one of them a pointer:
int* a, b, c;
means
int *a; int b; int c;
Think of the * as belonging to the variable name. Unintuitive, but that's the way the language works.
You want to declare all of the three as pointers:
int* a;
int* b;
int* c;
Change this
int* a, b, c;
to
int *a, *b, *c;
In your declaration you are declaring
a as pointer to int
b as int
c as int
The main problem, as others already noted, are the definitions here:
int* a, b, c;
Basically, only a is an int *; b and c are just ints.
It's just better to have one variable definition per line:
int* a = &a1;
int* b = &a2;
int* c = &a3;
If you use these raw pointers, and if for some reason you want to first define them and then assign their values later, consider at least initializing them to nullptr (or NULL if you are using C++98/03):
// Initialize to NULL/nullptr, to avoid pointers pointing to junk memory
int* a = nullptr;
int* b = nullptr;
int* c = nullptr;
....
// assign proper values to pointers...
Moreover, there are also other notes that can be made for your code:
int main(void)
Since this is C++ - not C - you can omit the (void), and just use () instead:
int main()
When you create the vector:
vector<int *> lol;
lol.clear();
you don't need to call its clear() method after the vector definition: in fact, vector's default constructor (implicitly called by the compiler when you defined the vector in the first line) has already initialized the vector to be an empty vector.
This is just fine:
vector<int *> lol; // Creates an empty vector
Considering these notes, your code can be written something like this:
#include <iostream>
#include <vector>
using namespace std;
int main()
{
vector<int *> lol;
int a1 = 1;
int a2 = 2;
int a3 = 3;
int * a = &a1;
int * b = &a2;
int * c = &a3;
lol.push_back(a);
lol.push_back(b);
lol.push_back(c);
cout << *lol[1] << endl;
}
First problem is at declaration of pointers
int* a, b, c;
This will create a as pointer and b & c as int.
Use declaration like
int* a,*b,*c;
And While accessing the elements of vector use .at() method of vector.
cout << *lol.at(0) << endl;
I just wanted to clarify something, imagine we have the function signature:
1) int* X(){}
2) int Y(){}
3) int& Z(){}
I am trying to work out the exhaustive possibilities of types of values I can return for the above. The below show possible implementations for the above function bodies:
1)
int* X(){
int* b = new int(6);
return b;
}
2)
int Y(){
int b = 6;
return b;
}
or
int Y(){
int* b = new int(6);
return *b;
}
EDIT: 2) not good because of memory leak if b isn't deleted.
3)
int& Z(){
int b = 6;
return b;
}
EDIT: 3) not good because b will go out of scope once function returns.
Is there anything I have missed out which could be returned from any of the above 3 function signatures? Getting a bit more adventurous, what about:
int* X(){
int b = 6;
return reinterpret_cast<b>;
}
and
int X(){
int* b = new int(6);
return reinterpret_cast<b>;
}
? (My understanding of reinterpret_cast may be wrong...)
int Y(){
int* b = new int(6);
return b*;
}
This has a syntax error. To dereference b, you would do *b. Nonetheless, this is a very bad implementation because it leaks memory. The dynamically allocated int will never be destroyed.
int& Z(){
int b = 6;
return b;
}
This is also bad because you are returning a reference to a local variable. The local variable b will be destroyed when the function returns and you'll be left with a reference to a non-existent object.
int* X(){}
when you have to return address which is pointing to integer
int Y(){}
for returning simple integer
int& Z(){}
this is something different,
you don't have any argument in Z() thus it is useless.
It must be like
int& Z(int &a)
{
//code body
return (a);
}
and return this to reference variable