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;
}
Related
I am so confused right now...
Here is the code that I will be talking about:
main.cpp:
#include "CustomVector.h"
#include <iostream>
int main() {
CustomVector<int, 15> hello{};
std::cout << hello.size() << '\n';
return 0;
}
CustomVector.h:
#pragma once
template<typename T, int S>
class CustomVector {
private:
T arr[S];
int size;
public:
CustomVector() : arr{}, size{ S } {}
// Methods
int size() const {
return size;
}
};
As you can see I am trying to use the size() method that I have in my class definition, which there shouldn't be a problem with, right..? But when I try to use it in main.cpp and try to print it out to the console, it is giving me the compiler error which my question title has. Why could this be, this has never happened to me before. I would think there is some sort of "redefinition" somehow, but how could that be, there couldn't be a redefinition if it is in my own user-defined class?
I am trying to use a custom comparator as in the following minimal example:
#include <set>
using namespace std;
struct idComp;
class TestClass
{
public:
int id;
void setId(int i){ id = i; }
int getId(){ return id; }
void test( set<TestClass*, idComp> &s){
//do my stuff
}
void test2(){
set <TestClass*, idComp> s;
}
};
struct idComp
{
bool operator() (TestClass* t1, TestClass* t2) const
{
return t1->getId() < t2->getId();
}
};
int main(int argc, char* argv[])
{
return 0;
}
...but when I try to compile I get the following error relating to the test function:
comp_ref.cpp:12:34: error: ‘idComp’ was not declared in this scope
void test( set<TestClass*, idComp> &s){
^~~~~~
comp_ref.cpp:12:40: error: template argument 2 is invalid
void test( set<TestClass*, idComp> &s){
and this with the addition of test2:
/usr/include/c++/7/bits/stl_tree.h:708:31: error: invalid use of incomplete type ‘struct idComp’
_Rb_tree_impl<_Compare> _M_impl;
Any suggestions of how/where to define idComp so that it is usable by the function test?
Since you have a bit of a circular dependency, you can resolve this by forward-declaring idComp before TestClass:
struct idComp;
class TestClass
{
...
But you can leave the definition of struct idComp where it is.
I am using C++ in native mode with Visual Studio 2017 and I am trying to compile and run the example code found at Debugging a Parallel Application in Visual Studio.
For the record, I program in C not C++. I am clueless when it comes to method declarations (among many other things). I suspect correcting the error is simple but, I simply don't know how.
In other words, I am currently RTFineM. I simply copied and pasted the example given in the url above and ran into 2 problems. First it complained about something being deprecated but a simple define took care of that problem. Second it complained about not being able to convert a type into another as stated in the title.
The RunFunc class causing the problem is declared as follows:
class RunFunc
{
Func& m_Func;
int m_o;
public:
RunFunc(Func func,int o):m_Func(func),m_o(o)
{
};
void operator()()const
{
m_Func(m_o);
};
};
My question/request is: how does the declaration of RunFunc need to be in order for the example to compile and run properly ?
Thank you, much appreciate the help.
In this constructor
RunFunc(Func func,int o):m_Func(func),m_o(o)
{
};
the prameter Func func is adjusted by the compiler to the type Func *func. On the other hand the data member m_Func is declared as a referenced type.
Func& m_Func;
And the error message says about incompatibility of the types.
C2440 cannot convert from 'void (_cdecl*)(int)' to 'void(_cdecl&)(int)
Try to declare the constructor like
RunFunc(Func &func,int o):m_Func(func),m_o(o)
{
};
Or declare the data member like
Func *m_Func;
without changing the constructor.
Here are two demonstrative programs
#include <iostream>
typedef void Func( int );
class RunFunc
{
Func& m_Func;
int m_o;
public:
RunFunc(Func &func,int o):m_Func(func),m_o(o)
{
};
void operator()()const
{
m_Func(m_o);
};
};
int main() {
return 0;
}
and
#include <iostream>
typedef void Func( int );
class RunFunc
{
Func *m_Func;
int m_o;
public:
RunFunc(Func func,int o):m_Func(func),m_o(o)
{
};
void operator()()const
{
m_Func(m_o);
};
};
int main() {
return 0;
}
In your code you are tyring to bound a reference to a temporary, namely to copy of argument passed to the constructor. You can try to run the following code snippet to see the difference:
struct Func {
int _i;
void operator()(int i) { cout << i*_i << endl; }
};
class RunFunc
{
Func& m_Func;
int m_o;
public:
RunFunc(Func &func, int o) :m_Func(func), m_o(o)
// RunFunc(Func func, int o) :m_Func(func), m_o(o)
{
};
void operator()()const
{
m_Func(m_o);
};
};
int main() {
Func f{ 5 };
RunFunc rf(f, 2);
rf();
return 0;
}
This is a legacy approach. You can use standard library functor and binder instead. For example:
#include <functional>
#include <iostream>
static void my_callback(int i) {
std::cout<< i << std::endl;
}
int _tmain(int argc, _TCHAR* argv[])
{
std::function<void()> functor;
functor = std::bind(my_callback, 1);
functor();
return 0;
}
I am having a hard time understanding the origin of these compilation errors.
Following code compiles without any problems on gcc-4.9.3 and clang-3.8 but is failing on VS 2013.
class Sample
{
public:
template<typename T>
explicit Sample(T& in) :
x(in),
lamb( [](Sample& ss)
{
std::cout << "This works !!\n" << static_cast<const T&> (ss.get()) << std::endl;
}){}
const int get() const { return x; }
private:
int x;
std::function<void(Sample&)> lamb;
};
int main()
{
int z = 10;
Sample a(z);
return 0;
}
I end up with following errors:
error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
error C2061: syntax error : identifier 'T'
The MSDN explaination for these errors did not help much. What am I doing wrong here?
It looks that visual studio doesn't pass info about template type T into lambda. I've passed class variable to lambda to gather needed type info. Something like this works:
#include <functional>
#include <iostream>
class Sample
{
public:
template<typename T>
explicit Sample(T& in) :
x(in),
lamb( [this](Sample& ss)
{
std::cout << "This works !!\n" << static_cast<decltype(x)> (ss.get()) << std::endl;
}){}
const int get() const { return x; }
private:
int x;
std::function<void(Sample&)> lamb;
};
int main()
{
int z = 10;
Sample a(z);
return 0;
}
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; }