I am trying to use templates in c++ [closed] - c++

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
#include <iostream>
using namespace std;
template <typename T>
void swap(T& i, T& j)
{
T temp = i;
i = j;
j = temp;
}
int main()
{
int m = 5, n = 10;
cout << "Inputs: " << m << "," << n << endl;
swap(m, n);
cout << "Outputs: " << m << "," << n << endl;
return 0;
}
However, I am getting compilation error. Can somebody help me to find the solution of this problem?

Your problem is using namespace std.
This is a perfect example of why "using namespace std;" screws you up when you least expect it with misleading and confusing error messages.
Remove "using namespace std" from your code, and always explicitly specify "std" when needed, i.e. std::cin, std::cout, etc....
You need to promise yourself that you will never write "using namespace std" ever again. Completely forget that this is a part of the C++ language.
The fixed version of your program, which compiles without any issues, is simply:
#include <iostream>
template <typename T>
void swap(T& i, T& j)
{
T temp = i;
i = j;
j = temp;
}
int main()
{
int m = 5, n = 10;
std::cout << "Inputs: " << m << "," << n << std::endl;
swap(m, n);
std::cout << "Outputs: " << m << "," << n << std::endl;
return 0;
}

swap() is already a defined function in the std namespace. Rename your method to something else.
using namespace std;
template <typename T>
void swaper(T& i, T& j)
{
T temp = i;
i = j;
j = temp;
}
int main()
{
int m = 5, n = 10;
cout << "Inputs: " << m << "," << n << endl;
swaper(m, n);
cout << "Outputs: " << m << "," << n << endl;
return 0;
}

The error message clearly says: error: call to 'swap' is ambiguous.
This is because swap is part of the namespace std.
And since you are using namespace std; - this is ambiguous!
You can solve this by either:
1.Remove the line using namespace std;
2.Rename the template function to something else

There is actually a number of problems in your code that cause the error message. And one contributor to the problem due to your implementation (i.e. the standard library you are using).
Firstly, you have defined a templated swap() with the same form (accepting two objects of the same type by reference) as an existing function named swap().
Second, the using namespace std tells the compiler that names in namespace std are candidates for matching names in your code. So, when the compiler sees your code swap(m,n) where m and n are int, it sees both your definition and the one in namespace std (i.e. std::swap() as viable candidates to match the name swap() in your code. Both candidates are able to accept two arguments of type (reference to) int, so the compiler has no reason to prefer one over the other. Hence it rejects your code with an error message about ambiguity.
The third problem is in your implementation (i.e. your compiler and its associated standard library) - <iostream> has apparently drawn in the definition of std::swap(). The problem is that <iostream> is neither required to do that (i.e. you cannot rely on it happening if you build your code with a different compiler) nor required not to (i.e. your code will compile alright with some compilers/libraries but not others).
In reality, std::swap() is required by the standard to be declared in <algorithm>, not in <iostream>.
Your options to get your code working with ALL compilers are therefore simple. A first option is to not define your own swap() at all, and rely on the standard library.
#include <iostream>
#include <algorithm> // Needed to guarantee visibility of std::swap()
using namespace std;
int main()
{
int m = 5, n = 10;
cout << "Inputs: " << m << "," << n << endl;
swap(m, n);
cout << "Outputs: " << m << "," << n << endl;
return 0;
}
A second option is to rename your function so it does not clash with std::swap().
#include <iostream>
using namespace std;
template <typename T>
void your_swap(T& i, T& j)
{
T temp = i;
i = j;
j = temp;
}
int main()
{
int m = 5, n = 10;
cout << "Inputs: " << m << "," << n << endl;
your_swap(m, n);
cout << "Outputs: " << m << "," << n << endl;
return 0;
}
A third option is to remove using namespace std from your code. This will allow you to safely declare your own swap(), without clashes with std::swap().
#include <iostream>
#include <algorithm>
template <typename T>
void swap(T& i, T& j)
{
T temp = i;
i = j;
j = temp;
}
int main()
{
int m = 5, n = 10;
std::cout << "Inputs: " << m << "," << n << std::endl;
swap(m, n);
std::cout << "Outputs: " << m << "," << n << std::endl;
return 0;
}
This last example will actually compile nicely - even with <algorithm> deliberately being used to draw in declarations of std::swap() - because the compiler has not been told to view names in std as candidates. It does require adding std:: prefixes to names in namespace std (std::cout, std::endl) that you intend to use. It will also compile nicely if swap(m,n) is replaced by std::swap(m,n).
A fourth option (which I normally would prefer in professional coding) is to rely on the standard library AND not employ using namespace std.
#include <iostream>
#include <algorithm> // Needed to guarantee visibility of std::swap()
int main()
{
int m = 5, n = 10;
std::cout << "Inputs: " << m << "," << n << std::endl;
std::swap(m, n);
std::cout << "Outputs: " << m << "," << n << std::endl;
return 0;
}
The short explanation of my preference for this option is that it avoids various other problems of ambiguity as well. The saved typing of not having to prefix std:: on names is not worth the trouble caused when other problems of ambiguity emerge.

Related

eigen: create Vector-like Replicate (access with one index, LinearAccessBit)

I want to create an Eigen::Replicate object that can be accessed like a vector, i.e. with a single index. I got that to work with the fixed-size replicate<Index,Index>(), which I can't use in reality, the non-one factor is not a compile-time constant. It also works when manually creating a Replicate object, but I feel like I'm just overlooking the obvious way of using a replicate function to achieve this:
#include <Eigen/Dense>
#include <iostream>
using namespace Eigen;
int main(){
Vector3i v (3);
v << 0,1,2;
constexpr int nReplications {2};
auto replDynamic { v.replicate(nReplications, 1) };
/* with a dynamic replication, two indexes are required to access a coeff */
std::cout << "5th entry: " << replDynamic(4,0) << '\n';
auto replFixed { v.replicate<nReplications, 1>() };
/* I want to use only one index, but I require the number of replications
* in one dimension to be dynamic */
std::cout << "5th entry: " << replFixed(4) << '\n';
/* don't know how to access the VectorwiseOp variant */
// auto replVector { v.replicate(nReplications) };
// std::cout << "5th entry: " << replVector(4) << '\n';
/* this function doesn't exist */
// auto replDefined { v.replicate<Dynamic,1>(nReplications, 1) };
// std::cout << "5th entry: " << replDefined(4) << '\n';
/* I'd rather not define it manually (it's not the intended way), but it works */
Replicate<Vector3i,Dynamic,1> replManual { v, nReplications, 1 };
std::cout << "5th entry: " << replManual(4) << '\n';
return 0;
}
The source code shows VectorwiseOp<...>::replicate(Index factor) in line 134, which sounds like what I need, but I don't seem to be able to access it.
And a function such as replicate<Index,Index>(Index,Index) doesn't exist.
Assuming I understand what you are asking, since a Vector3i is a one column Eigen::Matrix, you can get a VectorwiseOp<...> expression template from a Vector3i (say) by using the colwise() function and then call the one argument replicate with that.
That is,
#include <Eigen/Dense>
#include <iostream>
using namespace Eigen;
int main() {
Vector3i v(3);
v << 0, 1, 2;
auto foo = v.colwise().replicate(2);
std::cout << "5th entry: " << foo(4) << '\n';
return 0;
}
Note though that using type deduction on a expression template, or "pseudo expression" as they are called in the Eigen documentation, is generally a bad idea i.e. writing Eigen::Matrix<int, 6, 1> foo = v.colwise().replicate(2) is safer; the Eigen documentation mentions the issue here.
By adding a .reshaped() after the replicate(...) call, the ColsAtCompileTime are set to 1, and therefore, the resulting object can be accessed like a vector:
#include <Eigen/Dense>
#include <iostream>
using namespace Eigen;
int main(){
Vector3i v (3);
v << 0,1,2;
constexpr int nReplications {2};
auto replReshaped { v.replicate(nReplications, 1).reshaped() };
std::cout << "5th entry: " << replReshaped(4) << '\n';
return 0;
}

c++ - When I create a template I try to use it but get an error(C2668) and IntelliSense error

i create a template but get error.
the template and main (this code in one cpp file):
#include <iostream>
using namespace std;
template<class T>
void swap(T& x, T& y);
template<class T>
void swap(T& x, T& y){
T temp = x;
x = y;
y = temp;
}
int main(){
int n1 = 10, n2 = 5;
cout << "number before swap: num1= " << n1 << " num2= " << n2 << endl;
swap(n1, n2);//compilation error
cout << "number after swap: num1= " << n1 << " num2= " << n2 << endl;
system("pause");
return 0;
}
error:
Error 1 error C2668: 'std::swap' : ambiguous call to overloaded function
c:\projects\template\main.cpp 42 1 Template
2 IntelliSense: more than one instance of overloaded function "swap"
matches the argument list:
function template "void swap(T &x, T &y)"
function template "void std::swap(_Ty &, _Ty &)"
argument types are: (int, int) c:\Projects\Template\main.cpp 43
2 Template
why i get error i don't understand because all look fine.
thank's for the help.
thank's.
You are using using namespace std;. Because of this, the compiler has no way of knowing whether the line swap(n1, n2); means to use std::swap or your custom swap. You can resolve the ambiguity by explicitly specifying the namespace to use. You can use :: to specify the global namespace, which is where you defined your swap function. Try:
int main()
{
int n1 = 10, n2 = 5;
cout << "number before swap: num1= " << n1 << " num2= " << n2 << endl;
::swap(n1, n2);
cout << "number after swap: num1= " << n1 << " num2= " << n2 << endl;
return 0;
}
However, the real solution here is to remove using namespace std;. See here for an explanation of why this is a bad practice.
If you must have a using namespace std declaration and implement your own swap function, you can change your function name to start with an uppercase, Swap(). Since C++ is case-sensitive, that will avoid the clash, and therefore the ambiguity. It's better practice to use the Standard Library version, however.

this code compiles but doesnt show output when it runs (c++) in visual studio 2015 community

#include <conio.h> // include conio.h file
#include <iostream.h> // or #include<iostream>
int main()
{
int cout = 5;
cout << cout;
return 0;
}
Why does this happen ??
The code compiles correctly but it does not give expected output when it runs
This does not give the output 5 and all other stuff
It also does not give a warning.
The following line declares an int that happens to be called cout (it is not the std::cout stream)
int cout = 5;
The << operator peforms a bit shift.
So
cout << cout;
is only performing a bit shift and not storing the result.
To clarify, have a look at the following program:
#include<iostream>
int main()
{
int cout = 5;
auto shiftedval = cout << cout;
std::cout << "cout's value is " << cout << ", and the result of the bit shift is " << shiftedval << '\n';
return 0;
}
It will output:
cout's value is 5, and the result of the bit shift is 160
What is happening behind the scenes is that operator<< has been overloaded to take an ostream on the left hand side.
By including iostream you get this function and the compiler will know what you mean if you have an ostream to the left of the << operator.
Without a library the << would just simply have been a bitwise shift operator.
Also note that if you had ill-advisedly included using namespace std; or using std::cout then cout would then mean ostream and << would trigger a call to the library operator<< function. If after adding the using declaration above you include another declaration of cout the newly declared name will hide the previous declaration and cout will now be considered an int again and we're back to the bit shift operator functionality being used.
Example:
#include<iostream>
using namespace std; // using std:: at global scope
int main()
{
int cout = 5;
auto shiftedval = cout << cout;
//the following will not compile, cout is an int:
cout << "cout's value is " << cout << ", and the result of the bit shift is " << shiftedval << '\n';
//but we can get the cout from the global scope and the following will compile
::cout << "cout's value is " << cout << ", and the result of the bit shift is " << shiftedval << '\n';
return 0;
}
You are naming your variable cout, which you are confusing with std::cout. Your example preforms a bit shift operation. Try this instead :
int main()
{
int cout = 5;
std::cout << cout;
return 0;
}
Better yet, name your variable anything else to avoid the confusion :
int main()
{
int foo = 5;
std::cout << foo;
return 0;
}
If you don't explicitly declare the std namespace, either by including using namespace std; in your code or calling std::cout then cout resolves to the local variable cout in your main() function.
Even if you do declare using namespace std; cout will still resolve to the local variable instead - this is one reason why a lot of people, books, and tutorials will recommend that you explicitly write std::whatever instead of using the namespace.

C++ classes and variables

I'm relatively new to C++ programming. I'm studying how do classes work, and I have a problem with the following code:
#include <iostream>
using namespace std;
class time
{
public:
time();
void settime (int, int, int);
void printuniversal ();
void printstandard ();
private:
int hour;
int minute;
int second;
};
time::time()
{
hour = minute = second = 0;
}
void time::settime (int h, int m, int s)
{
hour = (h >= 0 && h < 24) ? h : 0;
minute = (m >= 0 && m < 60) ? m : 0;
second = (s >= 0 && s < 60) ? s : 0;
}
void time::printuniversal()
{
cout << hour << ":" << minute << ":" << second << ":" << endl;
}
void time::printstandard()
{
cout << ((hour == 0 || hour == 12) ? 12 : hour % 12) << ":" << minute << ":" << second << (hour < 12 ? "AM" : "PM") << endl;
}
int main ()
{
time t;
cout << "Initial universal time: " << t.printuniversal();
cout << "\nInitial standard time: " << t.printstandard();
t.settime(13,27,6);
cout << "\nNew universal time: " << t.printuniversal();
cout << "\nNew standard time: " << t.printstandard();
return 0;
}
The mistake I get is:
classi.cpp:42:6: error: expected ‘;’ before ‘t’
classi.cpp:43:39: error: ‘t’ was not declared in this scope
Is there something I didn't quite understand about classes? Why doesn't it recognize t a a "time" variable?
This should teach you not to have nasty using directives such as:
using namespace std;
And especially not at namespace scope (even worse if in header files). There is a function in the standard library called std::time(), whose name is clashing with the name of your type.
This ambiguity can be solved by using the class keyword in the declaration of t:
class time t;
However, a much better way would be to remove the using directive and qualify the names of entities from the standard namespace, thus writing (for instance):
std::cout << "Initial universal time: "
// ^^^^^
Notice, that this may not be enough, since library implementations are allowed to put entities from the C standard library in the global namespace. In this case, removing the nasty using directive would not help resolving the ambiguity.
Therefore, I would also suggest avoiding to give your own entities (types, functions, variables, ...) the same name as entities from the standard library, or to put them in your own namespace at least.
Moreover, expressions such as:
cout << "Initial universal time: " << t.printuniversal();
// ^^^^^^^^^^^^^^^^^^^^^
// printuniversal() returns void!
Are ill-formed, since printuniversal() returns void. You should just do:
cout << "Initial universal time: ";
t.printuniversal();
The same applies of course to all similar expressions
You shouldn't name your class time, or you should avoid using using namespace std. Instead, you can do statements like using std::cout, using std::endl, etc. I personally never use "using", always leave std::, it makes easier my searches in the source code.
Anyway, I checked here, removing using namespace std doesn't really help (see discussion above). Play safe and change name to the class. Anyway, the above suggestions stay.
An alternative to removing the "using namespace std" directive is to place your code in a namespace to avoid clashing names. This can be done as follows:
namespace time_utils
{
class time
{
public:
time();
void settime (int, int, int);
void printuniversal ();
void printstandard ();
private:
int hour;
int minute;
int second;
};
};
time_utils::time::time()
{
hour = minute = second = 0;
}
The purpose of namespaces is to avoid clashing names.
Later on there are compilation errors when calling functions in the cout stream, so you can split them up like so:
int main ()
{
my_code::time t;
cout << "Initial universal time: ";
t.printuniversal();
cout << "\nInitial standard time: ";
t.printstandard();
t.settime(13,27,6);
cout << "\nNew universal time: ";
t.printuniversal();
cout << "\nNew standard time: ";
t.printstandard();
return 0;
}
That's because those functions are returning void. The alternative there is to have those functions return std::string instead.
Hope this offers an alternative insight.
Cheers,
Simon.

std::cout not printing to console

#include <iostream>
void swap(int &pi, int &pj){
std::cout << "In function swap: " << &pi << " " << &pj << "\n";
int temp = pi;
pi = pj;
pj = temp;
}
int main(){
int i = 10, j = 20;
int *pi = &i, *pj = &j;
swap(pi, pj);
std::cout << *pi << " " << *pj;
return 0;
}
The above program does not give any compilation error. (Though to swap function in not POINTER TO REFERENCE type) and gives the proper output.
But whatever i am trying to print inside "swap" function is not printed to console.
Can anybody explain me why?
Looks like you're probably using std::swap to swap two pointers instead of calling your own swap routine. I suspect you have a using namespace std; somewhere that you are not showing us ? Try changing the name of your swap routine to e.g. my_swap and then see if calling my_swap works (it should fail with a compilation error).
If you can compile your program, you don't show us all of your code.
This code snippet you posted doesn't compile, because you're trying to pass to objects of type int* to your function swapm which expects a reference to an int.
If your code compiles, I suspect you to include a 'using namespace std;' anywhere in your original code.
you're trying to get the address of a pointer that you're passing by reference... I don't think you quite understand what you're doing. the pass by reference feature in C++ allows you to pass a reference, so you don't need a pointer. Your code should look like this.
#include <iostream>
void swap(int &i, int &j){
std::cout << "In function swap: " << i << " " << j << "\n";
int temp = i;
i = j;
j = temp;
}
int main(){
int i = 10, j = 20;
swap(i, j);
std::cout << i << " " << j;
return 0;
}