The code is working in that it couts haha but it causes an error because it says:
Process returned -1073741819 <0xC0000005>
And a window pops up telling me if I would like to send an error message. Why is this?
#include <iostream>
using namespace std;
template <class A>
A print( A a ) {
cout << a;
}
template <class T>
class David {
T a;
public:
David( T something ) : a( something ) {}
void laugh() {
print(a);
}
};
int main() {
David <string> Do("Hahaha");
Do.laugh();
}
template <class A>
A print( A a ) {
cout << a;
}
It`s incorrect. No return value in function, so, compiler returns some garbage from stack.
And better i think will be this declaration
template<class A>
void print(const A& a) { cout << a; }
Related
Consider following code snippet:
class Foo {
public:
void bar(std::size_t){}
void bar(const char* ){}
};
int main() {
auto foo = Foo{};
foo.bar(0);
}
It produces ambiguous calls errors (check here). But I think from programmer's perspective it is pretty obvious that I want to call overload with std::size_t. My question is if anything can be done so this code does not produce errors and calls size_t overload?
can be done like this in C++ 20
#include <cstdint>
#include <iostream>
#include <type_traits>
class Foo {
public:
template <typename T>
requires std::is_integral_v<T>
void bar(T){
std::cout<<"hello size_T";
}
void bar(const char* ){
std::cout<<"hello";
}
};
int main() {
auto foo = Foo{};
foo.bar(25);
}
In modern c++ (at least c++17), we prefer to pass string_view as argument over const char* for the none owner transfer cases, so a considerable choice:
#include <cctype>
#include <string>
class Foo {
public:
void bar(std::size_t){}
void bar(std::string_view){}
};
int main() {
auto foo = Foo{};
foo.bar(0);
}
Online demo
In below C++ 20, this works well.
#include <iostream>
class Foo {
public:
template <typename T>
void bar(T) {
std::cout << "hello T" << std::endl;
}
void bar(const char* c) {
std::cout << c << std::endl;
}
};
int main() {
auto foo = Foo{};
foo.bar(0);
foo.bar("test.");
}
This works in C++23:
foo.bar(0zu);
and this works pre-C++23:
foo.bar(size_t{0});
I want to call a template member function from a template function. This code is getting compiled in online compiler(http://coliru.stacked-crooked.com/a/5ff8acce3ceeb205) but when we try to compile the same code using visual studio 2015 we get error C2228: left of '.doSomething' must have class/struct/union. I need help to fix this error. Any help would be appreciated.
#include <iostream>
class A {
public:
template<class S>
int doSomething( S &s ) {
//Do something, for example just print
std::cout<< s <<std::endl;
return 0;
}
};
template<class S, class T>
int foo( S &s, T &v ) { return v.doSomething(s); }
int main(){
A a;
int x = 5;
foo(x,a);
return 0;
}
I am trying to use templates to create a mapping for understanding the concepts, but I am getting an error and failed to understand what I am doing wrong.
Can anyone take a look and let me know what I am doing wrong ? Please share a working example of a design if possible which I would really appreciate.
Thanks
#include <iostream>
#include <map>
using namespace std;
enum MathOperations
{
ADD = 0,
SUBTRACT,
MULTIPLY,
DIVISION
};
template <typename T>
T Addition(T a, T b)
{
return a + b;
}
template <typename T>
T Subtraction(T a, T b)
{
return a - b;
}
template <typename T>
struct MathOp
{
typedef T (*FuncPtr) (T, T);
};
/* I am getting a warning here, which says variable templates are c++1 extension */
template <typename T>
const std::map<MathOperations, typename MathOp<T>::FuncPtr> MathMap = {
{ MathOperations::ADD, &Addition<T> },
{ MathOperations::SUBTRACT, &Subtraction<T> }
};
int main ()
{
MathOp<int> mathIntObj;
/* I am getting error here */
/* No viable overloaded operator[] for type 'const std::map<MathOperations, typename MathOp<int>::FuncPtr>' */
std::cout << *(MathMap<int>[MathOperations::ADD])(1, 2) << endl;
return 0;
}
EDIT:
Thanks to #Piotr Skotnicki, who shared a solution for my error.
I had to make following changes:
std::cout << (*MathMap<int>.at(MathOperations::ADD))(1, 2) << endl;
Removed
MathOp<int> mathIntObj;
Still, I need to fix the warning. Any ideas ? Thanks
Why not use lambdas and the class template std::function, thus greatly reducing your code size:
#include <iostream>
#include <map>
#include <functional>
using namespace std;
enum MathOperations
{
ADD = 0,
SUBSTRACT,
MULTIPLY,
DIVISION
};
template <typename T>
const std::map<MathOperations, typename std::function<T(T,T)>> MathMap = {
{ MathOperations::ADD, [](T a, T b){ return a + b; } },
{ MathOperations::SUBSTRACT, [](T a, T b) { return a - b; } }
};
int main ()
{
std::cout << (MathMap<int>.at(MathOperations::ADD))(3, 2) << endl;
std::cout << (MathMap<int>.at(MathOperations::SUBSTRACT))(6, 5) << endl;
return 0;
}
driver.cc
#include <iostream>
#include "dynStack.h"
using namespace std;
// class definition
int main()
{
dynstack<double> it;
cout << "hello";
return 0;
}
dynStack.h
template <class T>
class dynstack {
public:
dynstack();
void push(T data);
private:
};
#include "dynStack.cc"
dynStack.cc
template <class T>
dynstack<T>::dynstack() { // <-- Here
}
template <class T> // // <-- And here
void dynstack<T>::push(T data)
{
}
I'm new to C++. The bolded lines are reported errors. The first one says "error: 'dynStack' does not name a type" The second one says "exrror: expected initializer before '<' token". I have spent hours on this and can't find the errors. Can anyone help? Thank you.
I was given a sample solution similar to this. Here is the sample:
main.cc
#include <iostream>
// #include the header file - as always
#include "temp.h"
using namespace std;
int main()
{
Thing<int> it(1);
Thing<double> dt(3.14);
cout << endl;
cout << "it = " << it.getData() << endl;
cout << endl;
cout << "dt = " << dt.getData() << endl;
cout << endl;
return 0;
}
temp.h
template <class T>
class Thing
{
private:
T data;
void setData(T data);
public:
Thing(T data);
T getData() const;
};
// MUST #include the implementation file here
#include "temp.cc"
temp.cc
// DO NOT #include the header file
template <class T>
Thing<T>::Thing(T data)
{
this->setData(data);
}
template <class T>
void Thing<T>::setData(T data)
{
this->data = data;
}
template <class T>
T Thing<T>::getData() const
{
return this->data;
}
It appears that you are trying to compile both driver.cc and dynStack.cc. The only file you compile with this setup is driver.cc.
Try this: Move contents of dynstack.cc entirely to dynstack.h and get rid of dynstack.cc
EDIT after reading comment responses:
If you want to keep dynstack.cc, its fine, just make sure you do not attempt to compile dynstack.cc I would name it a some other extension other than .cc which is conventionally for C++ implementation. Avoid .cc, .cpp, .cxx etc; use a uncommon extension such as .hc :-)
Have a problem about how to call the generic template version in a specialization version.
Here is the sample code. But the "vector::push_back(a)" calls itself recursively.
#include <iostream>
#include <vector>
using namespace std;
namespace std
{
template<>
void vector<int>::push_back(const int &a)
{
cout << "in push_back: " << a << endl;
vector::push_back(a); // Want to call generic version
}
}
int main()
{
vector<int> v;
v.push_back(10);
v.push_back(1);
return 0;
}
When you create specialization for some template (no difference class of function), you tell to compiler to generate that one instead of general. So in fact if you have specialization you have no general version for that specialization and you can't call it, because it doesn't exists.
You can simply extract the code into another template function:
template<typename T>
void baseF(T t) { ... }
template<typename T>
void F(T t) { baseF<T>(t); }
template<>
void F<int>(int t) { baseF<int>(t); }
Well, to complement, I think it works for template function specification in some situations.
#include <iostream>
#include <vector>
using namespace std;
class Base
{
public:
virtual int test() {return 0;}
};
class Derived : public Base
{
public:
virtual int test() {return 1;}
};
template<class T>
void TestOutput(T* a)
{
cout << a->test() << endl;
}
template<>
void TestOutput(Derived* a)
{
cout << "something else" << endl;
TestOutput<Base>(a);
}
int main()
{
Derived d;
TestOutput(&d);
}
I compiled it with visual studio 2013 and the output is:
something else
1
Although I don't think you can always find a TestOutput function of Base to call the generic one.