Below C++11 code won't compile (should work to my first impression) under g++ 4.9.2:
class A{};
class B : public A{};
void func(shared_ptr<B>){}
TEST(testFunc, testFunc_conv){
std::function<void(shared_ptr<A>)> afunc;
afunc = func;
}
The error messages indicate it doesn't accept the conversion from shared_ptr<B> to shared_ptr<A> though those B can be converted to A.
Why doesn't this work? Is it possible to work around this limitation?
EDIT
I consider the implications carefully and understand the reason - A can't be converted to B indeed, so it's not allowed for the sake of type safety.
The background of this code is to implement some generic interface with variadic parameters, so other part of the world can register a callable that taking derivatives of an empty base type. The callable would be called later (kind of deferred call):
//action would be stored for deferred call
// when action is actually called, it will use the real type
template<class ObjType>
registerInterface(function<void(Base*)> action, ObjType* obj){
function<void()> callable = [=]{ action(obj);}
//callable action would be stored for deferred call
}
void interfaceImpl(Derived* d){
d->realOperation();
}
//do registration - need to do the conversion each time for each interface implementation!
Derived d;
registerInterface(interfaceImpl, &d);
It would be annoying for each interfaceImpl to declare as taking the base type and do the downcasting brutely.
My solution is to remove the function from interface and set a implicit callable template argument for interfaceImpl to specify. Appreciate if there're better solutions.
If you want polymorphism, the declaration should include the parent class so you are able to pass its a children into it.
You are using a specific child in the definition, then trying to use the function with the base one. Obviously this would not work.
Either inherit from B or change the declaration to use the class A.
Note:
I am pretty sure you can do what you are trying to achieve in C++. However, the question you should ask yourself is: "Just because I can, should I really do it?" For example, just because you can abuse pointers to retrieve a private member of a class does not mean you should do it, and making an accessor will nearly always be the better choice.
Remember, code is being much more often read and reviewed than written. I would much rather see a straightforward code, than reading a pice of code including special constructs of the language just to make it work.
shared_ptr<B> is convertible to shared_ptr<A>. The buck stops here. Types below are not convertible:
shared_ptr<B>* to shared_ptr<A>*
void(*)(shared_ptr<B>) to void(*)(shared_ptr<A>)
function<void(shared_ptr<B>)> to function<void(shared_ptr<A>)>
This is for a good reason. What happens in the next fragment?
func (new A); // should not compile
afunc = func; // imagine this is allowed
afunc(new A); // now what?
Some of the conversions above but in the opposite direction do make sense, but C++ doesn't allow them for a number of historical and other reasons.
Fortunately you don't need any of this. You can do
template<class ObjType>
registerInterface(function action, ObjType* obj)
Or, better
registerInterface(std::function<void()> func) ...
And then call
register_interface(std::bind(funcA,objA));
register_interface(std::bind(funcB,objB));
You write "those 2 types are convertible". They are not.
Since B is a subtype of A, B can be assumed to hold additional members. Therefore it is not allowed to do what you are trying. You are saying specifically that func needs a ptr to B to operate on.
Then you create a function pointer that clearly states you will send something of type A. This can not work, because as stated B being the derived class may contain more members than A, members upon func may depend (since it specifies it explicitly as the argument type).
The other way around is polymorphically ok though. You could pass type B where type A is expected, because A being the base type, this would make it certain that B has the same members, thus it is safe to pass it (since it is of type A).
Related
Look at this snippet:
struct A {
void fn();
};
struct B: A {
};
void f() {
auto x = &B::fn;
}
Here, x gets a type of void (A::*)(), despite the fact that I've written &B::fn.
If I added fn into B, then type of x would be void (B::*)().
So, type of &B::fn changes whether B has a fn, or not.
What is the rationale behind this behavior? I find it surprising.
Why does this matter? Suppose this: programmer X creates A and B, like in my example. Programmer Y uses &B::fn, and uses the class-part of its type for something (like a parameter to a template, whatever). Then programmer X realizes, that he needs some extra functionality in fn, so he overrides it. Now, programmer Y's code can be broken, as type of &B::fn have changed.
This was the subject of CWG issue 203 and EWG issue 89. Initially, the rationale was to allow as much code as possible to be valid:
Notes from 04/00 meeting:
The rationale for the current treatment is to permit the widest possible use to be made of a given address-of-member expression. Since a pointer-to-base-member can be implicitly converted to a pointer-to-derived-member, making the type of the expression a pointer-to-base-member allows the result to initialize or be assigned to either a pointer-to-base-member or a pointer-to-derived-member. Accepting this proposal would allow only the latter use.
Later, after the problems caused by it had become more obvious, it was too late to fix:
Additional note, April, 2015:
EWG has determined that the utility of such a change is outweighed by the fact that it would break code. See EWG issue 89.
I think that the main idea comes from that usual "B is A" class inheritance definition. You can rephrase it for member functions like "functions of A are functions of B", however statement with flipped A and B position is correct only for some items, that is "only some functions of B are functions of A". So B::fn fits into this category of functions of B that are functions of A. By writing function fn in class B we at the same time move B::fn out of this category into category of functions of B that are not functions of A.
This allows one to check whether class overrides some method of base class:
const bool fn_is_overriden{::std::is_same<decltype(&A::fn), decltype(&B::fn)>::value};
In most ways, a member function is like a free function with an implicit object argument. So this code:
struct A {
void fn();
};
is very similar to:
struct A {};
void A_fn(A* this_);
For example, overload resolution between member functions and free functions is defined in this way, so that all of the functions can be ranked on the same footing.
When you inherit a member (variable or function), you inherit that function as it is. Inheritance doesn't define new functions or variables. All it does is create names in the derived class that refer to the existing members of the base class.
You've still got A_fn(A* this), just that it is accessible from B's scope. The access rules for inheritance apply to the inherited names only, they don't change any properties of the member.
I'm not sure if this is a thing (to be honest I want to say that it is not), but I was wondering if there is a way to write a c++ function so that it can choose which type of object to return.
For example, I have a base class (A) that has 3 child classes (Aa, Ab, Ac). In a factory(F) class I have a std::map<UINT, A*> that holds a number of the child classes based on a UINT id. My goal is to write a function that can build and return the correct object when I pass in an id value.
I'll probably end up returning pointers and cloning the data that they point to, but I was just curious as to whether or not the aforementioned was actually possible.
Thanks!
C++ being statically typed, the return type of a function must be known at compile time. From here arises the question:
do I know the expected return type statically on each call site of F (== it only depends on constant expression values)
or does it depend on some runtime variable.
For case #1, a function template for F would be a good approach.
But in your case, it seems you are facing #2 (because you want to return a type depending on ID that we can assume is not a constant expression).
Because of the static typing, if you are to write a function (assuming you do not overload it, because it seems your input parameters are always the same), it will have a single and well-defined return type. Basically, you do not have a syntax to say that your factory F will return either an Aa Ab or Ac (and that is a very good thing, with regard to static typing and all the compiler verifications it enables ; )
C++ solution: Type erasure
With that being said, you have a few approaches to type erasure, that will allow you to return an instance of a variant type hidden behind a common single type.
The obvious one is the pointer-to-derived to pointer-to-base conversion. It is particularly usefull if you plan to use the returned object mainly through its A interface (i.e., you will call the virtual functions defined on A).
A* F(ID aId)
This A* could point to any type deriving from A. From here, you could call every function defined on A public interface on the returned pointer. Of course, if you wanted to call an operation that is only available on a subclass, you would need to know what is the exact type on call site,and then cast the pointer to a pointer-to-derived before being able to call the operation.
A possible alternative, if you'd rather avoid dynamic memory, could be boost::variant. At the cost of having to explicitly list all the possible types the function could return.
boost::variant<Aa, Ab, Ac> F(ID aId);
You can take a look at the tutorial for a quick introduction to the syntax and features.
Sure, something like this:
class MyMapClass
{
public:
template< class ExactType > ExactType * getValue(UINT key)
{
return dynamic_cast<ExactType*>(_myMap.at(key));
}
BaseType * at(UINT key)
{
return _myMap.at(key);
}
private:
std::map<UINT, BaseType*> _myMap;
}
However, since you are storing the pointers to base types, you can as well return them as is, and rely on the caller to make a specific cast, if that goes well with your application's architecture.
Unfortunately, you can not do it fully automatically. Sooner or later you will have to determine the exact class that hides behind the base class pointer, and make a cast. With the template solution it is done "sooner":
MyDerivedType * value = myMapClassInstance.getValue<MyDerivedType>(1);
If you prefer to return the base pointer, it is done "later":
BaseType * value = myMapClassInstance.at(1);
MyDerivedType * exactValue = dynamic_cast<MyDerivedType*>(value);
I'm trying to convert the following C# code in to D, however I can't figure out how to make the template constraints work.
C# Implementation
public interface IComponent
{
}
public class Container
{
public T CreateComponent<T>() where T: IComponent, new()
{
// Trivial initialisation for example
var t = new T();
return t;
}
}
D Implementaiton
public interface Component
{
}
public class Container
{
public T createComponent(T)()
{
// Trivial initialisation for example
auto t = new T();
return t;
}
}
How can I re-create the "where T: IComponent" constraint?
I've tried various expressions combining is, typeof etc. but can't find anything that works.
Well, if all you're trying to do is require that T implement the interface IComponent, then is(T : IComponent) will test that T is implicitly convertible to IComponent (which is the case when IComponent is a base class of T or an interface that it implements). So, you'd end up with something like
public class Container
{
public T createComponent(T)()
if(is(T : IComponent))
{
// Trivial initialisation for example
auto t = new T();
return t;
}
}
Now, technically, other stuff can match if alias this is used to define an implicit conversion, which isn't likely to be common, but if you're being more paranoid about it, you could make the constraint also check that T is class - is(T == class).
public class Container
{
public T createComponent(T)()
if(is(T == class) && is(T : IComponent))
{
// Trivial initialisation for example
auto t = new T();
return t;
}
}
Then, T must be a class, and it must implicitly convert to IComponent. However, it is still technically possible for T to be a class which doesn't implement IComponent but does define an alias this which converts to an IComponent (it's just no longer possible for T to be a struct which does that). So, it's not perfect, but I don't know of a way to ensure that an implicit conversion is done via inheritance rather than alias this. So, unfortunately, I don't know of a way to absolutely guarantee that T is a class which implements IComponent. The most that I know how to do is to ensure that it implicitly converts to an `IComponent, which almost always means that it implements it.
However, the reality of the matter is that in the vast majority of cases, simply checking is(T : IComponent) is plenty, and depending on how your code is written, it might even work with a type which implicitly converts to IComponent but isn't actually an IComponent. So, the fact that alias this throws a spanner in the works may not actually be a problem. However, in general, alias this is a bane of generic code and why most generic code shouldn't be checking for implicit conversions. It's far too easy for a type to implicitly convert via alias this but not actually be converted in the function, in which case, it either won't compile, or it could have strange behavior if it supports the same operations that the target type does but those operations don't have the same results as they would if the original type were actually converted to the target type. So, if you actually want implicit conversions in templated code, you should force the implicit conversion by assigning the argument to the target type. But since you're looking to test for an interface rather than implicit conversions in general, what you probably want is a test which tests for that without allowing implicit conversions via alias this. Unfortunately, the only way that I know of to check at compile time whether one type derives from another or implements a specific interface is to check whether it implicitly converts to that base class or interface.
But maybe there's some fun voodoo with traits that's actually able to do it. If there is, we should probably add something to std.traits which does that for you, and if there isn't, maybe we should find a way to add it, since alias this can definitely be annoying if you don't want it. But fortunately, it's not a problem that comes up in most code, and if you're not writing a public API, then you only have to worry about it if you're declaring types with alias this. If you're not, then it really doesn't matter.
You don't even need a template constraint, just a template specialization:
T createComponent(T : IComponent)() { /* some code */ }
In typical fashion I found the answer moments after asking here http://ddili.org/ders/d.en/is_expr.html
public T addComponent(T)()
if (is(T: Component))
I am referring to one of the exercises mentioned in the book "thinking in c++.
Below code snippet throws an error for the call h.play, which i understand, because
the member i is private. But I was expecting the same error for the call me.play. If i comment the call h.play the code compiles fine. Why there is no error for the call me.play ?
class Buddy {};
template<class T> class My {
int i;
public:
void play(My<Buddy>& s) {
s.i = 3;
}
};
int main() {
My<int> h;
My<Buddy> me, bud;
h.play(bud);
me.play(bud);
}
Thankyou.
[Edit] Is there a way to see what code the compiler has generated for
My<int> h and
My<Buddy> me
? (anything similar to -E compiler flag) ?
Members are always "public" to instances of another object with the same type.
Meaning a My<Buddy> instance (such as me) can access private members of another My<Buddy> instance (such as bud).
Keep in mind that My<int> is a completely different type than My<Buddy>, and so it cannot access those members.
Because the play method is defined as taking a reference to My<Buddy> rather than a My<T>, the effective class is the same type when called on another instance of My<Buddy>. Therefore private members are accessible.
Unlike in languages that just pretend to have strong static type system and generics (looking at you Java), C++ allows you to disambiguate statically parametric types (template types) based on the parameters (the parameters being usually types) the types are templated on.
Note: You can also use a derived (dynamically / late bound) type as a parameter for a statically parametrized type, but it's not relevant in this scenario.
In other words, in C++:
typeid(me) == typeid(bud) will be TRUE
typeid(h) == typeid(me) will be FALSE
even though the type "My" is the same.
You can access the private data-members from the same type as though they were public, but as you can see, the second comparison is false because the operands are not of the same type, therefore you violate the access restrictions of the type.
Also, I don't think there is any way to take a look at the compiler-generated code. (As far as I know.)
Given the following template:
template <typename T>
class wrapper : public T {};
What visible differences in interface or behaviour are there between an object of type Foo and an object of type wrapper<Foo>?
I'm already aware of one:
wrapper<Foo> only has a nullary constructor, copy constructor and assignment operator (and it only has those if those operations are valid on Foo). This difference may be mitigated by having a set of templated constructors in wrapper<T> that pass values through to the T constructor.
But I'm not sure what other detectable differences there might be, or if there are ways of hiding them.
(Edit) Concrete Example
Some people seem to be asking for some context for this question, so here's a (somewhat simplified) explanation of my situation.
I frequently write code which has values which can be tuned to adjust the precise performance and operation of the system. I would like to have an easy (low code overhead) way of exposing such values through a config file or the user interface. I am currently writing a library to allow me to do this. The intended design allows usage something like this:
class ComplexDataProcessor {
hotvar<int> epochs;
hotvar<double> learning_rate;
public:
ComplexDataProcessor():
epochs("Epochs", 50),
learning_rate("LearningRate", 0.01)
{}
void process_some_data(const Data& data) {
int n = *epochs;
double alpha = *learning_rate;
for (int i = 0; i < n; ++i) {
// learn some things from the data, with learning rate alpha
}
}
};
void two_learners(const DataSource& source) {
hotobject<ComplexDataProcessor> a("FastLearner");
hotobject<ComplexDataProcessor> b("SlowLearner");
while (source.has_data()) {
a.process_some_data(source.row());
b.process_some_data(source.row());
source.next_row();
}
}
When run, this would set up or read the following configuration values:
FastLearner.Epochs
FastLearner.LearningRate
SlowLearner.Epochs
SlowLearner.LearningRate
This is made up code (as it happens my use case isn't even machine learning), but it shows a couple of important aspects of the design. Tweakable values are all named, and may be organised into a hierarchy. Values may be grouped by a couple of methods, but in the above example I just show one method: Wrapping an object in a hotobject<T> class. In practice, the hotobject<T> wrapper has a fairly simple job -- it has to push the object/group name onto a thread-local context stack, then allow the T object to be constructed (at which point the hotvar<T> values are constructed and check the context stack to see what group they should be in), then pop the context stack.
This is done as follows:
struct hotobject_stack_helper {
hotobject_stack_helper(const char* name) {
// push onto the thread-local context stack
}
};
template <typename T>
struct hotobject : private hotobject_stack_helper, public T {
hotobject(const char* name):
hotobject_stack_helper(name) {
// pop from the context stack
}
};
As far as I can tell, construction order in this scenario is quite well-defined:
hotobject_stack_helper is constructed (pushing the name onto the context stack)
T is constructed -- including constructing each of T's members (the hotvars)
The body of the hotobject<T> constructor is run, which pops the context stack.
So, I have working code to do this. There is however a question remaining, which is: What problems might I cause for myself further down the line by using this structure. That question largely reduces to the question that I'm actually asking: How will hotobject behave differently from T itself?
Strange question, since you should be asking questions about your specific usage ("what do I want to do, and how does this help me or hurt me"), but I guess in general:
wrapper<T> is not a T, so:
It can't be constructed like a T. (As you note.)
It can't be converted like a T.
It loses access to privates T has access to.
And I'm sure there are more, but the first two cover quite a bit.
Suppose you have:
class Base {};
class Derived : Base {};
Now you can say:
Base *basePtr = new Derived;
However, you cannot say:
wrapper<Base> *basePtr = new wrapper<Derived>();
That is, even though their type parameters may have an inheritance relationship, two types produced by specialising a template do not have any inheritance relationship.
A reference to an object is convertible (given access) to a reference to a base class subobject. There is syntactic sugar to invoke implicit conversions allowing you to treat the object as an instance of the base, but that's really what's going on. No more, no less.
So, the difference is not hard to detect at all. They are (almost) completely different things. The difference between an "is-a" relationship and a "has-a" relationship is specifying a member name.
As for hiding the base class, I think you inadvertently answered your own question. Use private inheritance by specifying private (or omitting public for a class), and those conversions won't happen outside the class itself, and no other class will be able to tell that a base even exists.
If your inherited class has its own member variables (or at least one), then
sizeof(InheritedClass) > sizeof(BaseClass)