0

I'd like to make some basic wrapper classes around simple types in C++. Since you can't just inherit from base types like you should be able to, I'm just using a wrapper class. The problem is, I want to be able to cast directly to that type, since that cast would be totally valid. The compiler just doesn't let you and I can't find a way to tell it that it's ok without running a cast method which kills performance. Is there any way to do this?

Here's what I have for the conversion constructor:

class Integer32
{ 
    public: 
    Integer32(int value) { this->Value = value; } 
    int Value; 
};

Does the compiler know to skip that and just assign it directly from an int? How do I test this to make sure since it's rather important...

Ryan Brown
  • 1,017
  • 1
  • 13
  • 34
  • Have you tried anything? – David G Jan 04 '13 at 03:01
  • 1
    You would have to define a conversion constructor, but why should that kill performance? It would be inlined and may in many cases end up a no-op. – jogojapan Jan 04 '13 at 03:03
  • 3
    @David: That's a silly question. He doesn't know the syntax or idiom to accomplish the task he's after. What should he do? Should he just type random characters in his editor and hope it compiles and does what he wants? – Benjamin Lindley Jan 04 '13 at 03:07
  • 1
    "Since you can't just inherit from base types like you should be able to..." -- I hope that one day you recognize the folly in this sort of thinking, C++ isn't Ruby and it's good at different things. – dash-tom-bang Jan 04 '13 at 03:08
  • @dash-tom-bang: And I hope one day *you* realize the folly in *that* sort of thinking. Why *shouldn't* you be able to inherit from base types? I can think of a reason (the same reason that applies to classes without virtual destructors, yet that's legal), but it shouldn't be dismissed just because it's traditionally the domain of easier to use languages. Making C++ easier to use is a good thing, as long as it doesn't violate the "you don't pay for what you don't use" rule. – Benjamin Lindley Jan 04 '13 at 03:19
  • 1
    Two more comments: (1) Whether the type `int` is really 32-bits depends on the platform. Calling your type `Integer32` may be misleading (use `int32_t` instead of `int` if you want to be sure). (2) Proper member initialization in the constructor is generally better, i.e. `Integer32(int value) : Value(value) {}` for the constructor definition. – jogojapan Jan 04 '13 at 03:19
  • Ah ty! Yeah when inheriting base classes obviously you couldn't do multiple inheritence on that object but otherwise it would be fine. – Ryan Brown Jan 04 '13 at 04:46
  • Boost has some support (ugly macro, but still) for creating arithmetic type wrappers. Better use that. – Cheers and hth. - Alf Jan 04 '13 at 05:45
  • @BenjaminLindley Different strokes I guess; I would have a serious conversation with anyone on my team who tried to do this as it adds complexity and brings no functional gain. – dash-tom-bang Jan 05 '13 at 01:50

1 Answers1

3

Provide a non-explicit constructor to allow conversion and casting from a base type to your wrapper. Provide a non-explicit conversion operator to allow conversion casting from your wrapper to a base class.

class my_wrapper {
    my_wrapper(int); // casting from int
    operator int();  // casting to int
};

(make them explicit to allow explicit casting but not implicit conversion)

Pubby
  • 51,882
  • 13
  • 139
  • 180
  • well this works except that casting from int needs a method to go with it, i just want to cast it without running any code (for performance) – Ryan Brown Jan 04 '13 at 03:08
  • 3
    @RyanBrown it will get inlined with no overhead. – Pubby Jan 04 '13 at 03:09
  • Ok are you 100% sure of this? I just don't want to build math libraries and such around this if it's not going to be as fast. – Ryan Brown Jan 04 '13 at 03:16
  • @RyanBrown No doubt. Compilers can inline much more fancy stuff than this: http://stackoverflow.com/questions/4860762/c-can-compilers-inline-a-function-pointer Never underestimate the compiler (and the power of C++). – jogojapan Jan 04 '13 at 03:17
  • @RyanBrown 100% certain if you compile with optimizations on. Inlining trivial code is something you can always rely on the compiler to do. – Pubby Jan 04 '13 at 03:18
  • Oh so it's not going to be nearly as fast initializing lots of integers without optimizations on... could be a huge downside since most development time is without optimizations – Ryan Brown Jan 04 '13 at 03:20
  • 1
    @RyanBrown No, it's not a downside. You shouldn't care about performance when debugging. Anyway, most compilers have a way to force inlining on certain functions, you could look into that if you really care. – Pubby Jan 04 '13 at 03:22
  • Well it looks like there's extra overhead on doing the basic math operator overloading without optimizations on... that's really not going to cut it for graphics libraries and such. I mean is it possible to overload + and get it just as fast as the base types without optimizations? – Ryan Brown Jan 04 '13 at 03:35
  • 2
    @RyanBrown: You're never going to get anywhere programming if you're more concerned with unprofiled performance than getting your code to work in the first place. It's fast enough until your data says it isn't. – GManNickG Jan 04 '13 at 03:44
  • Well I only want to make a wrapper class if it's going to be better than the base type. Without optimizations on the base type add is 10 times faster. Can't seem to turn on optimizations because I'm a windows C++ noob and it's requiring and can't find StdAfx.h or whatever. Here is my add function: Integer32 operator+(Integer32 integer) { return (BasicInteger32)integer + (BasicInteger32)this; } – Ryan Brown Jan 04 '13 at 04:03
  • @RyanBrown Why are you writing this in the first place? How is it better than the base type? – Pubby Jan 04 '13 at 04:08
  • So you can do simple operations on it without specifying the type. Is there a way to do this like with extensions in C#? Integer32 i; i.DoSomething(); – Ryan Brown Jan 04 '13 at 04:15
  • @RyanBrown Use templates. What you're doing is very bad C++. – Pubby Jan 04 '13 at 04:18
  • It's only bad C++ because you can't inherit or wrap a basic type correctly/efficiently... How would templates help? – Ryan Brown Jan 04 '13 at 04:28
  • 2
    @RyanBrown: Let me get this straight: you're new to C++, don't know the language well, let alone the idioms, cannot compile for optimizations, and you're going to say *you* know the best way to do it and are going to blame your failing on the language? You think you're in a position to say what C++ can and can't do efficiently? You should find your help elsewhere if you're going to act like that. – GManNickG Jan 04 '13 at 04:49
  • New to C++ on Windows, not in general. I could compile with optimizations on just fine at work. Ideally you just inherit the base type, I don't have to know everything about C++ to know it's a limitation if you can't do it. – Ryan Brown Jan 04 '13 at 04:56
  • Which IDE do you use? In Visual Studio enabling optimizations is just a matter of switching configuration from Debug to Release... – Spook Jan 04 '13 at 05:36
  • Yeah it was using precompiled headers on release mode and I took all that out in debug, I fixed it – Ryan Brown Jan 04 '13 at 06:08