【问题标题】:How to select the correct function overload? [duplicate]如何选择正确的函数重载? [复制]
【发布时间】:2016-04-22 12:10:02
【问题描述】:

在以下情况下选择正确的函数重载的正确方法是什么?

#include <iostream>
#include <algorithm>

/** the correct overload **/
bool predicate( const char& c )
{
    return c == '0';
}

/** the wrong overload **/
template< typename CharType >    
bool predicate( const CharType& c, int some_other_parameters )
{
    return c == '0';
}

std::string
process_string( const std::string& str )
{
    std::string result;
    std::copy_if( str.begin( ),
                  str.end( ),
                  std::back_inserter( result ),
                  predicate );

    return result;
}

int main()
{
    std::cout << process_string("AK0NNDK0ASDAS0") << std::endl;
    return 0;
}

【问题讨论】:

    标签: c++ c++11 overloading stl-algorithm template-function


    【解决方案1】:

    您可以使用 lambda 自行解决谓词歧义;

    std::string
    process_string( const std::string& str )
    {
        std::string result;
        std::copy_if( str.begin( ),
                      str.end( ),
                      std::back_inserter( result ),
                      [](char const& c) { return predicate(c); } );
        //            ^^ use the lambda to call the correct overload
    
        return result;
    }
    

    同样重要的是要记住,非模板将优先于模板函数。

    或者,您可以强制转换函数指针(但我认为这更麻烦);

    std::copy_if( str.begin( ),
                  str.end( ),
                  std::back_inserter( result ),
                  static_cast<bool(*)(const char&)>(&predicate) );
    

    Demo.

    指针转换的变体包括键入函数指针类型,然后获取指向所需函数的局部变量;

    using predicate_t = bool(*)(const char&);
    predicate_t my_predicate = &predicate;
    std::copy_if( str.begin( ),
                  str.end( ),
                  std::back_inserter( result ),
                  my_predicate );
    

    Demo.


    关于哪个选项更好,这取决于示例之外代码的复杂性、它们的位置(即您的代码与第三方代码)、模糊错误的数量以及谓词本身。

    鉴于 OP 代码中的简单条件,lambda 可以包含测试本身。在这种情况下,lambda 非常简单。

    如果计数很高,则更高范围的using 版本(带有用于指针转换的局部变量)可能是合适的。

    如果是“一次性”问题,static_cast 也可以。尽管演员阵容看起来“格格不入”。

    最终,它可能最受个人偏好的影响(或指南,如果您有任何涵盖这种情况的指南)。

    lambda 还可以与auto&amp;&amp; 和一些可变参数列表as seen in this answer in the linked question 的更现代用法结合使用。值得牢记的是,这些现代技术非常吻合。大多数现代编译器也对这种情况下的 lambda 表示乐观,因此使用它没有成本(这适用于这里的所有选项,都只是解决歧义)。

    理想情况下,一开始就不应该有模棱两可的情况,但它确实发生了,我们需要在找到它的上下文中以最合适的方式处理它。

    【讨论】:

    • 我只是在输入static_cast 答案,+1 添加它。这将是对 lambda 的不良使用,尽管我希望编译器会消除它。
    • 不过,我认为使用 lambda 是过早的悲观。
    猜你喜欢
    • 2015-05-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-17
    • 1970-01-01
    • 2013-06-02
    • 2020-01-03
    • 1970-01-01
    相关资源
    最近更新 更多