代码之家  ›  专栏  ›  技术社区  ›  Steve Guidi

需要默认参数值的模板函数的首选设计是什么?

  •  1
  • Steve Guidi  · 技术社区  · 16 年前

    template <typename T, typename U, typename V>
    void doWork(const T& arg1, const U& arg2, V* optionalArg = 0);
    

    当我调用这个模板时,我希望这样做如下。

    std::string text("hello");
    doWork(100, 20.0, &text);
    doWork('a', text);         // oops!
    doWork<char, std::string, void>('a', text);  // to verbose!
    

    不幸的是,第二次调用没有编译,因为编译器无法推断可选参数的类型。这是不幸的,因为我真的不关心参数类型是什么,而是它的值是空的。另外,我希望避免第三次调用的路径,因为它会妨碍可读性。

    这让我尝试使用模板参数 V 有一个默认类型,这也不起作用,因为您不能将默认类型应用于函数模板参数(至少使用VC++9.0)。

    template <typename T, typename U, typename V = void>  // oops!
    void doWork(const T& arg1, const U& arg2, V* optionalArg = 0);
    

    我唯一剩下的选择是引入超负荷的 doWork 它对模板参数一无所知 v .

    template <typename T, typename U>
    void doWork(const T& arg1, const U& arg2)
    {
        doWork(arg1, arg2, 0);
    }
    
    template <typename T, typename U, typename V>
    void doWork(const T& arg1, const U& arg2, V* optionalArg);
    

    这是解决这个问题的最好办法吗?我看到的唯一缺点是,如果函数模板包含许多具有适当默认值的参数,我可能会引入许多琐碎的转发函数。

    3 回复  |  直到 16 年前
        1
  •  5
  •   CB Bailey    16 年前

    我认为您的转发函数是一个非常合适的解决方案,尽管在您的解决方案中,您不需要显式地指定模板参数吗?(0是一个整数常量,可以转换为任何 V* 类型。)也 doWord vs doWork

    作为一般规则,尽量避免选择没有很好回报的参数。

    信息技术 可以 更容易强制您的功能客户机只添加一个 , (void*)0

        2
  •  2
  •   xtofl Adam Rosenfield    16 年前

    从客户机代码的角度来看,如果它没有第三个参数,为什么它需要发明一个呢?

    因此,如果你的目标是可用性和可读性,我同意你的包装方法:它有完美的意义,而且包装 write负责第三个参数的适当值 必须的。

    除此之外,如果需要,还可以为不同的专门化使用不同的默认值。

        3
  •  0
  •   UncleBens    16 年前

    一种可能是对模板参数进行重新排序,因此首先是可选参数。

    template <typename V, typename T, typename U>
    void doWork(const T& arg1, const U& arg2, V* optionalArg = 0);
    
    doWork<void>('a', text); 
    

    不过,默认参数和模板似乎并不匹配。