So, I have a fairly simple set of templates that I want to use together, but the compiler keeps telling me that B::a has incomplete type. Everything is forward declared, but it still doesn't work...
#include <iostream>
using namespace std;
template <typename T> class A;
template <typename T> class B;
template <typename T>
class A{
public:
void ATestFunction();
void CallBFunction();
protected:
B<T> b;
};
template <typename T>
class B{
public:
void BTestFunction();
void CallAFunction();
protected:
A<T> a;
};
template <typename T>
void A<T>::ATestFunction(){
cout << "A was used for a function call" << endl;
}
template <typename T>
void B<T>::BTestFunction(){
cout << "B was used for a function call" << endl;
}
template <typename T>
void A<T>::CallBFunction(){
b.BTestFunction();
}
template <typename T>
void B<T>::CallAFunction(){
a.ATestFunction();
}
int main()
{
A<int> dragons;
dragons.CallBFunction();
return 0;
}
I ask this because I had run into some difficulty programming some array type classes that depend on each other (implementing a two dimensional array that can be accessed like this: [][]), but this problem happened and threw a gear in the works. I made this testing program, but it still fails. I've tried both MinGW 4.7.2 and GNU g++ on Linux, and each gave me the same problem.
The core of the issue can be seen in this piece of code:
template <typename T>
class A{
B<T> b;
};
template <typename T>
class B{
A<T> a;
};
C++ is a language with value semantics, that means that B<T> b; represents an object of type B<T> (rather than a reference, like in Java or C# with reference types). That is, A<T> contains a B<T>. Now if you look at the definition of the B template you see that in turn it contains an A<T> sub object. This is basically impossible, as A<T> cannot possibly contain an object that contains A<T>. What would be the size of an A<T> object?
Without knowing the real problem to solve, I won't venture to recommend an approach, but you can consider using pointers (A<T> would contain a pointer to B<T>, not a full B<T> sub object; or similarly, B<T> could contain a pointer to A<T>; or both), or references. But it might also be the case that a deeper redesign could make more sense.
Even if you used pointers, that could not work. That would basically trigger an infinite loop of A´s and B´s being created
A creates B creates A creates B creates A...
this would work.
#include <iostream>
using namespace std;
template<typename T> class A;
template<typename T> class B;
template<typename T>
class A
{
public:
A()
{
b = new B<T>(this);
}
A(B<T>* pb)
{
b = pb;
}
void ATestFunction()
{
cout << "A was used for a function call" << endl;
}
void CallBFunction()
{
b->BTestFunction();
}
protected:
B<T>* b;
};
template<typename T>
class B
{
public:
B()
{
a = new A<T>(this);
}
B(A<T>* pa)
{
a = pa;
}
void BTestFunction()
{
cout << "B was used for a function call" << endl;
}
void CallAFunction()
{
a->ATestFunction();
}
protected:
A<T>* a;
};
int main()
{
A<int> dragons;
dragons.CallBFunction();
B<int> bdragons;
bdragons.CallAFunction();
return 0;
}
or maybe just using static functions
#include <iostream>
using namespace std;
template<typename T> class A;
template<typename T> class B;
template<typename T>
class A
{
public:
static void ATestFunction()
{
cout << "A was used for a function call" << endl;
}
void CallBFunction();
};
template<typename T>
class B
{
public:
static void BTestFunction()
{
cout << "B was used for a function call" << endl;
}
void CallAFunction();
};
template<typename T>
void A<T>::CallBFunction()
{
B<int>::BTestFunction();
}
template<typename T>
void B<T>::CallAFunction()
{
A<int>::ATestFunction();
}
int main()
{
A<int> dragons;
dragons.CallBFunction();
B<int> bdragons;
bdragons.CallAFunction();
return 0;
}
Related
#include <functional>
#include <iostream>
class Plain {
public:
template <typename Type>
void member_function(const Type& s) {
std::cout << "Recived: " << s << std::endl;
}
};
template <typename Type>
class Templated : private Plain {
public:
};
int main() {
Plain b;
b.member_function<int>(10); // done!
Templated<int> d;
// d.member_function(); /* how to achive this */
return 0;
}
I am trying to call the member function in class Plain by two method:
createing non-templated class and padding type while calling function
Plain p;
p.member_function<int>();
passing type while creating class and calling without template param
Templated<int> t;
t.member_function(); // achive this
I tried doing binding the function in derived class like
struct Plain{
template<typename T>
static void member_function(const T& s){std::cout << s << std::endl;}
}
template<typename T>
struct Templated : private Plain {
std::function<void(const T&)> print = Templated::Plain::member_function;
}
and after that I was able to do
Templated t<std::string>;
t.print();
When you use private inheritance the methods in Plain are inaccessible to outside code, and you need to have something inside of Templated make the call to the method in Plain; you can do so, or alternatively you could use public inheritance and be able to hit it directly.
class Plain {
public:
template <typename T>
void print(const T & s) {
std::cout << "Received: " << s << std::endl;
}
};
template <typename T>
class Templated : private Plain {
public:
void print(const T & s) {
Plain::print<T>(s);
}
};
template <typename T>
class Alternative : public Plain {};
int main() {
Templated<int> t;
t.print(3); // This could work
Alternative<int> a;
a.print(4); // As could this
return 0;
}
I found a workaround
#include <functional>
#include <iostream>
using namespace std::placeholders;
struct Test {
template <typename Type>
void foo(const Type&) {
std::cout << "I am just a foo..." << std::endl;
return;
}
};
template <typename T>
struct Foo {
private:
Test* obj;
public:
Foo() : obj(new Test) {}
std::function<void(const int&)> foo = std::bind(&Test::foo<T>, obj, _1);
~Foo() { delete obj; }
};
int main() {
Foo<int> me;
me.foo(10);
Test t;
t.foo<int>(89);
std::cout << std::endl;
return 0;
}
I'm sure there is a very easy answer, but I can't figure it out. I have written a templated class, but I want to pass that class by reference in a class function that isn't templated. Heres what I have. I get a bunch of errors. All I need to do is figure how to format the way to insert templated class into function, but I'm at a lost. Thank you and sorry if the code doesn't really help you out.
#include <iostream>
using namespace std;
template <typename T>
class Foo {
public:
Foo();
insert(const T& Item)
//And other function, just examples
};
class noFoo(){
void test(Foo <T>& foo);
int i;
int j;
int k
};
template <typename T>
void noFoo::test(Food <T>& foo)}
cout << "hi";
}
int main() {
Foo<char> wr;
test(wr);
return 0;
}
Make test a function template. I also corrected loads of syntax errors for you (class noFoo()?), removed unnecessary code, and ran clang-format for indentation.
#include <iostream>
template <typename T>
class Foo {};
class noFoo
{
public:
template <typename T>
void test(Foo<T> &);
};
template <typename T>
void noFoo::test(Foo<T> &)
{
std::cout << "hi\n";
}
int main()
{
Foo<char> wr;
noFoo{}.test(wr);
}
Since your question is tagged d, here the same code in D.
import std.stdio;
class Foo(T) {};
class noFoo
{
public:
void test(T)(Foo!(T))
{
writeln("hi");
}
};
void main()
{
auto wr = new Foo!char;
(new noFoo).test(wr);
}
Is it possible to create a class template with a member function definition only if the object created is of a specific type?
I've created a template class I will use for storing either int or doubles, but for doubles I would like to be able to set precision too (objects created with myclass < double> should have this functionality, but for myclass< int> there is no need for that to be present at all).
I know I can use a base class template, and create new classes "myInt", "myDouble" using that and implement the functionality only in the myDouble class, but I think it would be cleaner to define the functionality (both the function and a member variable) for doubles in the class template, if that's possible and preferable?
Let's add an example to show what I want to do:
#include <iostream>
#include <iomanip>
class commonBase{
public:
void setState(int state);
virtual void print() = 0;
private:
int _my_state;
};
template <typename T>
class generalObject : public commonBase {
public:
void value(T value);
void print(){ std::cout << "My value: " << _my_value << std::endl; }
private:
T _my_value;
};
template <typename T>
void generalObject<T>::value(T value){
_my_value = value;
}
// Is there any way do specialize only only whats different from the generalObject template?
// Here I thought I could specialize the case where a generalObject is created of <double>, but
// when I do, nothing is derived from generalObject (or at least not visible as far as I can tell)
template<>
class generalObject<double>{
public:
void setPrecision(int precision){ _my_precision = precision; }
// here I would like a special implementation of print(), which overrides the print() in generalObject
// and instead also prints according to the precision set when the object is of <double> type.
// Row below an example which doesn't work (compiler error, _my_value undefined)
void print(){ std::cout << "My value: " << std::setprecision(_my_precision) << _my_value << std::endl; }
private:
int _my_precision;
};
int main(int argc, char* argv[]){
generalObject<int> o1;
o1.value(1);
o1.print();
o1.setState(1); //inherited from the commonBase
generalObject<double> o2;
o2.setPrecision(2);
o2.value(2); //here value isn't available (compile error)
o2.print();
o2.setState(123); //also isn't available (compile error)
}
Sure.
template <typename T> class Poly;
void set_precision(Poly<double>* self, int a) {};
If you really want dot notation you can then add:
template <typename T> class Poly {
public: void set_precision(int a){::set_precision(this,a);}
...
However I think you should think about what you're trying to accomplish. If MyInt and MyDouble have different fields and different methods and different implementations, they should probably be different classes.
This can be solved using template specialization.
We first define a common template...
template< typename T >
struct myclass
{
// common stuff
};
... and specialize that for double:
template<>
struct myclass<double>
{
int precision = 10;
void setprecision( int p ){ precision = p; }
};
Now the setprecision() method can only be called for myclass<double>. The compiler will complain if we try to call it for anything else, like myclass<int>.
int main()
{
myclass<double> d;
d.setprecision( 42 ); // compiles
myclass<int> i;
i.setprecision( 42 ); // fails to compile, as expected
}
Demo.
The basic way to have a member function of a class template exist only for some template parameters is to create a specialization of the class template for those template parameters.
template<typename T>class X{
// general definition
};
template<>class X<double>{
// double-specific definition
};
The downside of this is that the specialization will need to duplicate anything that is common. One way to address this is to move the common things out to a base class template:
template<typename T>class Xcommon{
// common stuff
};
template<typename T>class X: public Xcommon<T>{
// general definition
};
template<>class X<double>: public Xcommon<double>{
// double-specific definition
};
Alternatively, you can do it the other way: put the common stuff in the derived class, and the extras in the base, and specialize the base:
template<typename T>class Xextras{
// empty by default
};
template<typename T>class X: public Xextras<T>{
// common definition
};
template<>class Xextras<double>{
// double-specific definition
};
Either way can work; which is better depends on the details.
Both these methods work for data members and member functions.
Alternatively, you can use enable_if to mean that member functions are not selected by overload resolution if the template parameter doesn't meet a required condition. This requires that the member function is itself a template.
template<typename T>class X{
template<typename U=T> // make it a template,
std::enable_if<std::is_same_v<U,double>> double_specific_function(){
// do stuff
}
};
I wouldn't recommend this option unless there is no other choice.
If the question is about a member function, then here is one of the ways to do it without class template specialization:
#include <iostream>
#include <type_traits>
template <typename T>
struct Type {
template <typename U = T,
typename = typename std::enable_if<std::is_same<U, double>::value>::type>
void only_for_double() {
std::cout << "a doubling" << std::endl;
}
};
int main() {
Type<int> n;
Type<double> d;
// n.only_for_double(); // does not compile.
d.only_for_double();
}
Example on ideone.com
If you require a data-member presence based on the template parameter, you will have to do some kind of specialization, in which case it is, probably, simpler to put the function into corresponding specialization.
EDIT: After OP made his question more specific
Here is one way to do it without extra class and getting rid of virtual functions. Hope it helps.
#include <iostream>
#include <iomanip>
template <typename T, typename Derived = void>
class commonBase {
public:
void setState(int state) {
_my_state = state;
}
void value(T value) {
_my_value = value;
}
template <typename U = Derived,
typename std::enable_if<std::is_same<U, void>::value,
void * >::type = nullptr>
void print() const {
std::cout << "My value: " << _my_value << std::endl;
}
template <typename U = Derived,
typename std::enable_if<!std::is_same<U, void>::value,
void * >::type = nullptr>
void print() const {
static_cast<Derived const *>(this)->_print();
}
protected:
T _my_value;
int _my_state;
};
template <typename T>
class generalObject : public commonBase<T> {
};
template<>
class generalObject<double> : public commonBase<double, generalObject<double>> {
private:
friend commonBase<double, generalObject<double>>;
void _print() const {
std::cout << "My value: " << std::setprecision(_my_precision) <<
_my_value << std::endl;
}
public:
void setPrecision(int precision){ _my_precision = precision; }
private:
int _my_precision;
};
int main(){
generalObject<int> o1;
o1.value(1);
o1.print();
o1.setState(1);
generalObject<double> o2;
o2.setPrecision(2);
o2.value(1.234);
o2.print();
o2.setState(123);
}
Same code on ideone.com
I am kind of C++ newbie, especially when dealing with templates. I have a template class "Foo" that is intended to take different structures as template parameters. I need also to have a member function of the class that works differently depending on the type template parameter, so I specialise such a function. The general picture would be as follows
struct A
{
float paramOfA;
};
struct B
{
float paramOfB;
};
template <typename T>
class Foo
{
public:
void doSomethingOnType(T& arg);
//...more functions and stuff...
};
// function specialisation for A's
template<> void Foo<A>::doSomethingOnType(A& a){
//do something on member of A
a.paramOfA = ...;
std::cout<< "I've done something on a's member..."<<std::endl;
}
// function specialisation for B's
template<> void Foo<B>::doSomethingOnType(B& b){
//do something on member of B
b.paramOfB = ...;
std::cout<< "I've done something on b's member..."<<std::endl;
}
So far so good, right? Imagine that now I have a structure C that derives from B:
struct C:B
{
float paramOfC;
};
Now, when I instantiate a Foo object that takes C structure template type, I would want the function "doSomethingOnType" to keep the same behaviour of the function for B types on C's member that derives from B (paramOfB), eventhough I haven't specialised such a function for C structure types. For instance
Foo<C> o;
C oneC;
o.doSomethingOnType(oneC);
I am sure that when executing the above piece of code, the function will take any implementation given in the templated class, not in the specialised version for B. But I really want to keep the latter implementation of the function when using C types since, being C derived from B, it would make a lot of sense to me as well as saving me time from having to write more lines of code for a function specialisation for C's that has the same behaviour than for B (imagine that B has 50 members instead of a single one). Is it possible to do so without, as I said, specialising the function for C structure types?
Thanks a lot in advance for any help!
Really excited to ask me first question in stackoverflow :-)
You can do some hook thing in general template function, though I hate it....
these code can as following:
template <typename T>
class Foo {
public:
void doSomethingOnType(T& arg)
{
if (dynamic_cast<B*>(&arg) != NULL) {
Foo<B> fb;
fb.doSomethingOnType(arg);
} else {
std::cout << "I've done something on Foo's member..." << std::endl;
}
}
};
Although How do you force a templatization to match a base class? is an elegant solution if your function takes an instance of T as a parameter, I would like to introduce several ways if it does not:
TestCase
class A1 {};
class A2:public A1 {};
class B{};
class C{};
Wrapped Function
This might be the simplest solution:
template<typename T>
class Bar
{
public:
void fun()
{
fun_impl((T*)(0));
}
void fun_impl( A1* const)
{
cout << "A1" << endl;
}
void fun_impl(B* const)
{
cout << "B" << endl;
}
void fun_impl(void*)
{
cout << "Neither A nor B" << endl;
}
};
Bar<A2>().fun(); // A1
Bar<B>().fun(); // B
Bar<C>().fun(); // Neither A nor B
Because the precedence of fun_impl which exactly matches(or as an accessible base class of) the type > those which requires void* conversion, the correct version will be enabled.
(NOTE: This is true on clang3.7 and gcc5.3, but I din't refer to standard)
However, if we haveclass A3: private A1, an error will be raised during the compilation of Bar<A3>().fun().
The following two solutions require C++11:
Partial Specialization of Class Template
template<typename T, bool = std::is_base_of<A1, T>::value,
bool = std::is_base_of::value >
struct Foo
{
void fun();
}; //Main Version
template<typename T>
struct Foo<T,false,false>
{
void fun();
}; //Specialization of Neither A nor B
template<typename T>
void Foo<T,false,false>::fun()
{
cout << "neither A nor B" << endl;
}
template<typename T>
struct Foo<T,true,false>
{
void fun();
}; //Specialization of A
template<typename T>
void Foo<T,true,false>::fun()
{
cout << "A" << endl;
}
template<typename T>
struct Foo<T, false, true>
{
void fun();
}; //Specialization of B
template<typename T>
void Foo<T,false,true>::fun()
{
cout << "B" << endl;
}
Foo<A2>().fun(); //A
Foo<B>().fun(); //B
Foo<C>().fun(); //Neither A nor B
Foo<APrivate>().fun(); //A
SFINAE
If you don't want to specialize the whole class, maybe SFINAE in one class could be the best choice:
namespace
{
class Helper1 {};
class Helper2 {};
} // Helper classes to avoid ambiguity
template<typename T>
class Foo
{
public:
template<typename TIn= T, typename U= typename std::enable_if<std::is_base_of<A1, TIn>::value>::type >
void fun(Helper1 = Helper1())
{
cout << "A" << endl;
}
template<typename TIn=T ,typename U = typename std::enable_if<std::is_base_of<B, TIn>::value>::type >
void fun(Helper2 = Helper2())
{
cout << "B" << endl;
}
template<typename TIn = T, typename = typename std::enable_if<!std::is_base_of<A1,TIn>::value>::type ,
typename = typename std::enable_if<!std::is_base_of<B,TIn>::value>::type >
void fun()
{
cout << "Neither A nor B" << endl;
}
};
In the case above a function will be instantiated only if it matches some certain conditions. Since three void fun() are not allowed in one class, helper classes are required.
Suppose we have template class
template <typename T>
class MyTem{
public:
bool is_T_Pointer(){
<...>
}
};
class Cls : MyTem<Cls>{
<...>
};
int main(void){
Cls* classOnHeap = new Cls(); /* T is pointer */
Cls classOnStack; /* T is not pointer */
<...>
}
I know this is a bad example but if someone could help me find out if T is pointer from template class that would be great.
Remember we have inheritance with template of same class as base class.
Doesn't have to be complete implementation, a vague technique will be enough
You should employ partial specialization here:
template<class T>
class A
{
public:
A() {}
};
template<class T>
class A<T*>
{
public:
A(int) {}
};
Then the following will not compile, because compiler is forced to choose pointer version of template and there is no default constructor:
A<char*> a;
this does compile:
A<char> a;
If the compiler supports C++11 use std::is_pointer:
#include <iostream>
#include <type_traits>
template <typename T>
class MyTem
{
public:
static const bool IS_POINTER = std::is_pointer<T>::value;
};
int main()
{
std::cout << MyTem<char*>::IS_POINTER << "\n";
std::cout << MyTem<char>::IS_POINTER << "\n";
return 0;
}
See demo http://ideone.com/Mo394 .