I'm trying to use the pimpl idiom to hide some grungy template code, but I can't give derived classes of the body class friend access to the handle class. I get an error C2248 from MSVC 9 sp1. Here's some code to duplicate the error:
//
// interface.hpp
//
namespace internal{
template<class T>
class specific_body;
}
class interface
{
struct body;
body *pbody_;
interface(body *pbody);
template<class T>
friend class internal::specific_body;
public:
~interface();
interface(const interface &rhs);
bool test() const;
static interface create( bool value );
};
//
// interface.cpp
//
struct interface::body
{
virtual ~body(){}
virtual bool test() const = 0;
virtual interface::body *clone() const = 0;
};
class true_struct {};
class false_struct {};
namespace internal {
template< class T>
class specific_body : public interface::body
{ // C2248
public:
specific_body(){}
virtual bool test() const;
virtual interface::body *clone() const
{
return new specific_body();
}
};
bool specific_body<true_struct>::test() const
{
return true;
}
bool specific_body<false_struct>::test() const
{
return false;
}
} //namespace internal
interface::interface(body *pbody) : pbody_(pbody) {}
interface::interface(const interface &rhs) : pbody_(rhs.pbody_->clone()) {}
interface::~interface() { delete pbody_; }
bool interface::test() const
{
return pbody_->test();
}
interface interface::create(bool value )
{
if ( value )
{
return interface(new internal::specific_body<true_struct>());
}
else
{
return interface(new internal::specific_body<false_struct>());
}
}
//
// main.cpp
//
// #include "interface.hpp"
//
int _tmain(int argc, _TCHAR* argv[])
{
interface object( interface::create(true));
if ( object.test() )
{
// blah
}
else
{
}
return 0;
}
Any help would be appreciated, I'm trying to hide interface::body and specific_body implementations from the users of interface if that's not obvious from my question.
You need to add template<> in the explicit instantiation of the template test method
template<> // add this line
bool specific_body<true_struct>::test() const
{
return true;
}
You haven't qualified specific_body. Try
template<class T>
friend class internal::specific_body;
as your friend declaration.
Try using typename maybe? I think I read in Sutter that typename will work to get to class inside of an unknown scope, while class won't.
In addition to the unqualified specific_body mentioned by Troubadour, your specialization attempt of specific_body<>::test for true_struct and false_struct seems incorrect. You have to specialice the full class.
To solve the problem, I'd simply declare body in the public section. Declaring specific_body to be a friend of interface::body in addition doesn't help either.
Well, I was able to "solve" this problem by making the body a public declaration in the interface. That solves the C2248 error during the declaration of the specific_body. I also made the body a friend to the interface class and added a method to the body struct:
static interface create( body *pbody )
{
return interface(pbody);
}
so that a specific_body can create an interface if there is a nested relationship between instances of specific_body
Related
I am writing Interface and Invoker class that allows a class to be several type of invoker and several type of interface.
I don't manage to fix ambiguities in compilation when the function have no parameters ( so all versions have same signature ).
I tried to templatize the function so I can specialize when calling, but It still not removing the ambiguities.
I Know there several article here that talk about similar issue, but they are all with a parameter in the method so the signature is different for each specialization which remove the ambiguity.
I wrote a sample project as small as possible to show.
The workaround for the function Invoker::Interfaces is to add a parameter in the function, and they I can call with (IMyInterface*)0 , but this is ugly .
The workaround for the function Invoker::Register, is to static cast the parameter, but with a template it should find automatically the type of the parameter and I shouldn't need that.
Some help would be very grateful. So I could remove those ugly workarounds.
Thanks a lot.
Here the sample code.
template interface base class
template <class INVOKER>
class Interface
{
public:
INVOKER& Invoker() { return *m_invoker; }
private:
template <typename> friend class Invoker;
INVOKER* m_invoker;
};
template Invoker base class:
template <class INTERFACE>
class Invoker
{
public:
template<class I>
void Register(INTERFACE* _interface) { m_interfaces.push_back(_interface); }
void Register(INTERFACE* _interface) { m_interfaces.push_back(_interface); }
std::vector<INTERFACE*> Interfaces() { return m_interfaces; }
std::vector<INTERFACE*> Interfaces(INTERFACE*) { return m_interfaces; }
template<class I>
std::vector<INTERFACE*> Interfaces() { return m_interfaces; }
private:
std::vector<INTERFACE*> m_interfaces;
};
A short as possible of multi inheritance usage:
class DogLover;
class InterfaceDog : public Interface<DogLover>
{
public:
virtual bool AskIfGoodBoy() = 0;
};
class CatLover;
class InterfaceCat : public Interface<CatLover>
{
public:
virtual void Pet() = 0;
};
class DogLover : public Invoker<InterfaceDog> {};
class CatLover : public Invoker<InterfaceCat> {};
class PetLover
: public DogLover
, public CatLover
{
public:
using DogLover::Register;
using DogLover::Interfaces;
using CatLover::Register;
using CatLover::Interfaces;
int Size() { return m_size; }
void DoStuff()
{
for (InterfaceDog* interface : Interfaces((InterfaceDog*)0))
{
interface->AskIfGoodBoy();
}
/*
for (InterfaceCat* interface : Interfaces<InterfaceCat>()) << ambigous
{
interface->Pet();
}*/
}
private:
int m_size = 0;
};
class PetOwner
: public InterfaceCat
, public InterfaceDog
{
//using InterfaceDog::Invoker;
//using InterfaceCat::Invoker;
void Pet() override { /* Invoker().Size(); */}
bool AskIfGoodBoy() override { return true; }
};
Main :
int main()
{
PetLover petLover;
PetOwner petOwner;
//petLover.Register<DogLover>(&petOwner); // << ambigous
//petLover.Register<CatLover>(&petOwner); // << ambigous
petLover.Register(static_cast<InterfaceDog*>(&petOwner));
petLover.Register(static_cast<InterfaceCat*>(&petOwner));
}
Thanks to #fabian (https://stackoverflow.com/users/2991525/fabian)
I forgot the obvious simplest solution :) which it to specify the class which from you want to call the method like this
Interface:
for (InterfaceCat* interface : CatLover::Interfaces())
{
interface->Pet();
}
Register:
petLover.DogLover::Register(&petOwner);
petLover.CatLover::Register(&petOwner);
Invoker:
class PetOwner
: public InterfaceCat
, public InterfaceDog
{
void Pet() override
{
InterfaceDog::Invoker().Size();
}
I would like to inherit from a class with the const specifier like this:
class Property
{
int get() const;
void set(int a);
};
class ConstChild : public const Property
{
// Can never call A::set() with this class, even if
// the instantiation of this class is not const
};
class NonConstChild : public Property
{
// Can call both A::set() and A::get() depending on
// the constness of instantiation of this class
};
My compiler obviously gives me an error for the const keyword in the second classes declaration. Ideally I'd like to avoid having to create a new class ReadOnlyProperty from which ConstChild would inherit.
Can I somehow use the const keyword for inheritance?
If not, do you have any other ideas on how to solve this problem?
Introduce mutability later in your inheritance tree and derive appropriately:
class Property
{
int get() const;
};
class MutableProperty : public Property {
{
void set(int a);
};
And then:
class ConstChild : public Property { ... };
class MutableChild : public MutableProperty { ... };
I had the need for a related problem, which is: to really control/highlight mutable and const access on some class.
I did it with this simple reusable template wrapper:
template <typename T>
class TAccessor : private T
{
public:
const T& Const() const { return *this; }
T& Mutable() { return *this; }
};
// Example of use:
template <typename T>
using MyVector = TAccessor<std::vector<T>>;
void main()
{
MyVector<int> vector;
vector.Mutable().push_back(10);
int x = vector.Const()[1];
...
}
If you create a const member function set, you will get what you need.
class Property
{
int get() const;
void set(int a);
};
class ConstChild : public Property
{
void set(int a) const {}
};
The only caveat is that a sly user can circumvent your intention by using:
ConstChild child;
child.set(10); // Not OK by the compiler
Property& base = child;
base.set(10); // OK by the compiler
I would like to inherit from a class with the const specifier"
However much you want to is irrelevant. You cannot. That is not valid C++.
Can I somehow use the const keyword for inheritance?"
No.
Use a data member or private base class instead of public base class.
Then you control the access to that member.
You can make the Property thing an abstract interface if you need polymorphic behavior.
You can use a template class and a specialization for a constant type:
template<typename T> class base_property {
protected:
T value;
};
template<typename T> class property : public base_property<T> {
public:
const T& get()const { return value; }
void set(const T& v){ value = v; }
};
template<typename T> class property<const T> : public base_property<T> {
public:
const T& get()const { return value; }
};
class ConstChild : public property<const int>{ };
I had the same need and I ended up with this quite manual approach :
class A
{
public:
void fooMutable(void) {}
void fooConst(void) const {}
};
class B : private A
{
public:
using A::fooConst;
const A& getParent(void) const
{
return *this;
}
};
void fooParent(const A&) {}
int main(void)
{
auto b = B{};
b.fooConst(); // Ok
b.fooMutable(); // Fail
fooParent(b); // Fail
fooParent(b.getParent()); // Ok
return 0;
}
Note that the using keyword would not work with overloads const/mutable :
class A
{
public:
void foo(void) {}
void foo(void) const {}
};
class B : private A
{
public:
using A::foo; // Expose the const and the mutable version
};
To solve this you could redefine the function yourself and call the parent :
class B : private A
{
public:
void foo(void) const
{
A::foo();
}
};
It can become pretty time consuming if you're inheriting a large hierarchy, but if it's for a not-so-big class it should be very reasonable and being quite natural for the user.
I have a trick, not a clean solution.
class ConstChild : private Property
{
operator const Property () { return *this; }
};
then
ConstChild cc;
cc.set(10); // ERROR
cc().get();
I am trying to use CRTP to register all live (created but not yet destroyed) instances of some class. This works for me well:
template <typename T>
class Registrable {
public:
void _register(T* p) { instances_.insert(p); }
void _unregister(T* p) { instances_.erase(instances_.find(p)); }
static const std::set<T*> & instances() { return instances_; }
private:
static std::set<T*> instances_;
};
template <typename T>
std::set<T*> Registrable<T>::instances_;
class Class : private Registrable<Class> {
public:
using Registrable<Class>::instances;
Class() { _register(this); }
Class(const Class &) { _register(this); }
Class(Class &&) { _register(this); }
~Class() { _unregister(this); }
void function() { }
};
int main() {
Class c;
auto upc = std::make_unique<Class>(c);
std::vector<Class> vc(5);
for (auto i : Class::instances())
i->function();
}
EDITED:
Better would be not to care about registering and unregistering of instances in derived classes. Solution according to #Jean-BaptisteYunès and #Aconcagua:
template <typename T>
class Registrable {
public:
static const std::set<T*> & instances() { return instances_; }
protected:
Registrable() { instances_.insert(static_cast<T*>(this)); }
Registrable(const Registrable &) : Registrable() { }
Registrable(Registrable &&) : Registrable() { }
~Registrable() { instances_.erase(instances_.find(static_cast<T*>(this))); }
private:
static std::set<T*> instances_;
};
...
class Class : public Registrable<Class> { ... }
However, I am also not sure whether this type of casting is safe. Especially, if Class would additionally derive from another class via multiple inheritance.
The answer of #amc176 claims, that I can assume that the cast will be successful, but I would prefer to be sure. According to #Aconcagua's comment, I can be sure, just it's not in the answer.
static_cast makes no runtime checks to ensure the cast is completely safe. Anyway, as you know the type T will be a derived class of Registrable<T>, you can assume the cast will be successful.
In fact, in cppreference it's mentioned that this cast is typically used when applying CRTP (referred as static polymorphism in the link).
I would like to inherit from a class with the const specifier like this:
class Property
{
int get() const;
void set(int a);
};
class ConstChild : public const Property
{
// Can never call A::set() with this class, even if
// the instantiation of this class is not const
};
class NonConstChild : public Property
{
// Can call both A::set() and A::get() depending on
// the constness of instantiation of this class
};
My compiler obviously gives me an error for the const keyword in the second classes declaration. Ideally I'd like to avoid having to create a new class ReadOnlyProperty from which ConstChild would inherit.
Can I somehow use the const keyword for inheritance?
If not, do you have any other ideas on how to solve this problem?
Introduce mutability later in your inheritance tree and derive appropriately:
class Property
{
int get() const;
};
class MutableProperty : public Property {
{
void set(int a);
};
And then:
class ConstChild : public Property { ... };
class MutableChild : public MutableProperty { ... };
I had the need for a related problem, which is: to really control/highlight mutable and const access on some class.
I did it with this simple reusable template wrapper:
template <typename T>
class TAccessor : private T
{
public:
const T& Const() const { return *this; }
T& Mutable() { return *this; }
};
// Example of use:
template <typename T>
using MyVector = TAccessor<std::vector<T>>;
void main()
{
MyVector<int> vector;
vector.Mutable().push_back(10);
int x = vector.Const()[1];
...
}
If you create a const member function set, you will get what you need.
class Property
{
int get() const;
void set(int a);
};
class ConstChild : public Property
{
void set(int a) const {}
};
The only caveat is that a sly user can circumvent your intention by using:
ConstChild child;
child.set(10); // Not OK by the compiler
Property& base = child;
base.set(10); // OK by the compiler
I would like to inherit from a class with the const specifier"
However much you want to is irrelevant. You cannot. That is not valid C++.
Can I somehow use the const keyword for inheritance?"
No.
Use a data member or private base class instead of public base class.
Then you control the access to that member.
You can make the Property thing an abstract interface if you need polymorphic behavior.
You can use a template class and a specialization for a constant type:
template<typename T> class base_property {
protected:
T value;
};
template<typename T> class property : public base_property<T> {
public:
const T& get()const { return value; }
void set(const T& v){ value = v; }
};
template<typename T> class property<const T> : public base_property<T> {
public:
const T& get()const { return value; }
};
class ConstChild : public property<const int>{ };
I had the same need and I ended up with this quite manual approach :
class A
{
public:
void fooMutable(void) {}
void fooConst(void) const {}
};
class B : private A
{
public:
using A::fooConst;
const A& getParent(void) const
{
return *this;
}
};
void fooParent(const A&) {}
int main(void)
{
auto b = B{};
b.fooConst(); // Ok
b.fooMutable(); // Fail
fooParent(b); // Fail
fooParent(b.getParent()); // Ok
return 0;
}
Note that the using keyword would not work with overloads const/mutable :
class A
{
public:
void foo(void) {}
void foo(void) const {}
};
class B : private A
{
public:
using A::foo; // Expose the const and the mutable version
};
To solve this you could redefine the function yourself and call the parent :
class B : private A
{
public:
void foo(void) const
{
A::foo();
}
};
It can become pretty time consuming if you're inheriting a large hierarchy, but if it's for a not-so-big class it should be very reasonable and being quite natural for the user.
I have a trick, not a clean solution.
class ConstChild : private Property
{
operator const Property () { return *this; }
};
then
ConstChild cc;
cc.set(10); // ERROR
cc().get();
here's my problem.
I have a template abstract class RandomVariable with pure virtual function operator()()
template<T>
class RandomVariable<T> {
public:
virtual T operator()() = 0;
/* other stuff */
protected:
T value;
}
I also have a template abstract class Process with pure virtual function operator()()
template<T>
class Process<T> {
public:
typedef std::pair<double, T> state;
typedef std::list<state> result_type;
virtual result_type operator()() = 0;
/* other stuff */
protected:
result_type trajectory;
}
I can easily write a method returning generating a path and returning the last value of my trajectory.
T GenerateTerminalValue() {
this->operator()();
return value.back().second;
};
But it would be much better if, instead of returning type T my function actually returned a functor (ideally derived from RandomVariable) with overloaded operator() generating a path and returning the last value of the trajectory. My best try only led to a Segmentation Fault.
What would be a good way to do this? Thanks.
What about using std::function?
#include <functional>
template<typename T>
class MyClass {
public:
std::function<T()> GenerateTerminalValueFunc() {
return [this]() {
this->operator()();
return value.back().second;
};
}
...
};
Update: If you want to derive from RandomVariable you could try something like this:
#include <memory>
template<typename T>
class TerminalValueOp : public RandomVariable<T>
{
private:
MyClass<T>* obj_;
public:
TerminalValueOp(MyClass<T>* obj) : obj_(obj) {}
T operator()() {
obj->operator()();
return obj->value.back().second;
}
...
};
template<typename T>
class MyClass {
public:
std::shared_ptr<RandomVariable<T>> GenerateTerminalValueOp() {
return std::make_shared<TerminalValueOp<T>>(this);
}
...
};