Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.0k views
in Technique[技术] by (71.8m points)

c++ - How do I strongly typedef non-primitive types?

Observe the following program in which a function accepts both the expected type and any type that is a typedef of that type.

//a user defined type
class Widget{};

//a function that takes a Widget
void function (Widget w){}

int main(){

    //make a typedef (this is C++11 syntax for a typedef. It's the same thing)
    using Gadget = Widget;

    //make the two "different types" (well.. they're not really different as you will see)
    Widget w;
    Gadget g;

    //call a function that should ONLY accept Widgets
    function(w); //works (good)
    function(g); //<- works (I do not want this to compile though)

}

As you can see, a typedef does not actually distinguish a new type. I thought instead to inherit from the type:

//inherit instead
class Gadget: public Widget{};

//make the two "different types"
Widget w;
Gadget g;

//call the function that should ONLY accept widgets
function(w); //works (good)
function(g); //<- works (I do not want this to compile though)

Same problem.
Looking at boost, I thought to try a strong typedef:

#include <boost/serialization/strong_typedef.hpp>

//a user defined type
class Widget{};

//a function that takes the user defined type
void function (Widget w){}

int main(){

    //try to strongly typedef
    BOOST_STRONG_TYPEDEF(Widget, Gadget)

    //make the two "different types"
    Widget w;
    Gadget g;

    //call the function that should ONLY accept widgets
    function(w);
    function(g);

}

compile errors:

In member function ‘bool main()::Gadget::operator==(const main()::Gadget&) const’:
error: no match for ‘operator==’ (operand types are ‘const Widget’ and ‘const Widget’)
  BOOST_STRONG_TYPEDEF(Widget, Gadget)
  ^
In member function ‘bool main()::Gadget::operator<(const main()::Gadget&) const’:
error: no match for ‘operator<’ (operand types are ‘const Widget’ and ‘const Widget’)
  BOOST_STRONG_TYPEDEF(Widget, Gadget)
  ^

Apparently BOOST_STRONG_TYPEDEF only works on primitive types.
I tried to do inheritance again, but stop the implicit conversion:

//I want the functionality, but these are NOT the same type!
class Gadget: public Widget{
    operator Widget() = delete;
};

That did not work either.

Questions:

  1. Why does boost strong_typedef only work on primitive types?
  2. How can I 'typedef' a non-primitive type to get functionality similar to boost strong_typef?
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Basically you need two unrelated classes with the same behavior. I would use a parametrized template for that:

template<int tag> class WidgetGadget { ... };
typedef WidgetGadget<0> Widget;
typedef WidgetGadget<1> Gadget;

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...