C++ variadic template function parameter with default value

前端 未结 2 1749
忘掉有多难
忘掉有多难 2021-02-07 02:30

I have a function which takes one parameter with a default value. Now I also want it to take a variable number of parameters and forward them to some other function. Function pa

2条回答
  •  甜味超标
    2021-02-07 03:00

    No, packs must be last.

    But you can fake it. You can detect what the last type in a pack is. If it is SomeSpecialType, you can run your func. If it isn't SomeSpecialType, you can recursively call yourself with your arguments forwarded and fromNum(5) appended.

    If you want to be fancy, this check can be done at compile time (ie, a different overload) using SFINAE techniques. But that probably isn't worth the hassle, considering that the "run-time" check will be constant on a given overload, and hence will almost certainly be optimized out, and SFINAE shouldn't be used lightly.

    This doesn't give you the signature you want, but it gives you the behavior you want. You'll have to explain the intended signature in comments.

    Something like this, after you remove typos and the like:

    // extract the last type in a pack.  The last type in a pack with no elements is
    // not a type:
    template
    struct last_type {};
    template
    struct last_type {
      typedef T0 type;
    };
    template
    struct last_type:last_type {};
    
    // using aliases, because typename spam sucks:
    template
    using LastType = typename last_type::type;
    template
    using EnableIf = typename std::enable_if::type;
    template
    using Decay = typename std::decay::type;
    
    // the case where the last argument is SomeSpecialType:
    template<
      typename... Args,
      typename=EnableIf<
        std::is_same<
          Decay>,
          SomeSpecialType
        >::value
      >
    void func( Args&&... args ) {
      // code
    }
    
    // the case where there is no SomeSpecialType last:    
    template<
      typename... Args,
      typename=EnableIf<
        !std::is_same<
          typename std::decay>::type,
          SomeSpecialType
        >::value
      >
    void func( Args&&... args ) {
      func( std::forward(args)..., std::move(static_cast(fromNum(5))) );
    }
    
    // the 0-arg case, because both of the above require that there be an actual
    // last type:
    void func() {
      func( std::move(static_cast(fromNum(5))) );
    }
    

    or something much like that.

提交回复
热议问题