Default template parameters with forward declaration

后端 未结 4 1452
太阳男子
太阳男子 2020-12-25 14:35

Is it possible to forward declare a class that uses default arguments without specifying or knowing those arguments?

For example, I would like to declare a boo

相关标签:
4条回答
  • 2020-12-25 14:58

    Yes. Default template arguments may be specified any time, anywhere, so long as the declarations don't conflict with each other. They are ultimately merged together from the various declarations.

    Even this is legal:

    template< class A, class B, class C = long >
    class X;
    
    template< class A, class B = int, class C >
    class X;
    
    template< class A = short, class B, class C >
    class X { };
    

    A similar example is given in §14.1/10. According to that paragraph, function default arguments behave similarly.

    Good luck on getting the forward declaration to behave itself and not barf on everything!

    0 讨论(0)
  • 2020-12-25 15:00

    Well same issue here. But with STL.

    If one of my header use eg. std::vector then I have to include the entire header. From this time every time I include my header even if my source code does not refer to std::vector at all the header gets included along with my header. If you include this header in lots of place that will mean lots of overparsing.

    So I forward declared the std::vector and used std::vector* 's but my code don't want to compile due to the default arguments. If I place the default arguments in my header then the compiler refuses to compile the stl header due to the default argument respectification.

    What I'm trying to do in this situation is creating my own Vector class that adapts the std::vector and forwards every method call to it. Probably this could solve the problem.

    0 讨论(0)
  • 2020-12-25 15:03

    I don't think you can forward declare a template with default arguments unless the library in question provided its own forward declaration header. This is because you can't respecify the default arguments (even if they match... gcc will still report “error: redefinition of default argument”).

    So to the best of my knowledge the solution is for the library to supply a forward declaration header Foo_fwd.h:

    #ifndef INCLUDED_Foo_fwd_h_
    #define INCLUDED_Foo_fwd_h_
    template<class T, class U=char> class Foo; // default U=char up here
    #endif
    

    and then the full implementation in Foo.h would be:

    #ifndef INCLUDED_Foo_h_
    #define INCLUDED_Foo_h_
    #include "Foo_fwd.h"
    template<class T, class U> class Foo { /*...*/ }; // note no U=char here
    #endif
    

    So now your code could use Foo_fwd.h as well... but unfortunately, since this approach requires modifying the original Foo.h to remove the default arguments this doesn't scale to 3rd party libraries. Maybe we should lobby the C++0x crew to allow equivalent respecification of default template arguments, à la typedefs...?

    0 讨论(0)
  • 2020-12-25 15:14

    Any compilation unit that uses your facility that forward-declares boost stuff will need to include the boost headers anyway, except in the case that you have certain programs that won't actually use the boost part of your facility.

    It's true that by forward-declaring, you can avoid including the boost headers for such programs. But you'll have to manually include the boost headers (or have an #ifdef) for those programs that actually use the boost part.

    Keep in mind that more default template parameters could be added in a future Boost release. I'd advise against this route. What I would consider, if your goal is to speed compile times, is to use a #define to indicate whether the code using that boost library should be disabled. This way you avoid the forward declaration hassle.

    0 讨论(0)
提交回复
热议问题