簡體   English   中英

將 std::bind 與重載函數一起使用

[英]use std::bind with overloaded functions

我無法找到如何使用std::bind將參數綁定到重載的 function 。 std::bind無法以某種方式推斷出重載類型(對於其模板參數)。 如果我不超載 function 一切正常。 代碼如下:

#include <iostream>
#include <functional>
#include <cmath>

using namespace std;
using namespace std::placeholders;

double f(double x) 
{
    return x;
}

// std::bind works if this overloaded is commented out
float f(float x) 
{
    return x;
}

// want to bind to `f(2)`, for the double(double) version

int main()
{

    // none of the lines below compile:

    // auto f_binder = std::bind(f, static_cast<double>(2));

    // auto f_binder = bind((std::function<double(double)>)f, \
    //  static_cast<double>(2));

    // auto f_binder = bind<std::function<double(double)>>(f, \
    //  static_cast<double>(2));

    // auto f_binder = bind<std::function<double(double)>>\
    // ((std::function<double(double)>)f,\
    //  static_cast<double>(2));

    // cout << f_binder() << endl; // should output 2
}

我的理解是std::bind無法以某種方式推斷出它的模板參數,因為f已重載,但我不知道如何指定它們。 我在代碼中嘗試了 4 種可能的方法(注釋行),但均無效。 如何為std::bind指定 function 的類型? 任何幫助深表感謝!

你可以使用:

auto f_binder = std::bind(static_cast<double(&)(double)>(f), 2.);

要么

auto f_binder = bind<double(double)>(f, 2.);

或者,可以使用lambda:

auto f_binder = []() {
    return f(2.);     // overload `double f(double)` is chosen as 2. is a double.

};

重載的 function 名稱只能在某些允許推斷單個所需重載的上下文中使用。 例如,重載名稱可以用作 static_cast 的參數(如@Jarod42 的回答)或用作賦值的右側:

void foo() { std::cout << "foo()" << std::endl; }
void foo(int, float) { std::cout << "foo(int, float)" << std::endl; }

int main() {
  /* foo denotes all overloaded foo-s. ptr denotes only one.
   * foo(0, 0) and foo() are both valid
   * ptr(0, 0) is valid, ptr() is not */
  void (*ptr)(int, float) = foo;
  auto f = std::bind(ptr, 0, 0);
  f();
  auto g = std::bind(static_cast<void (*)(int, float)>(foo), 0, 0);
  g();
}

一旦選擇了一些重載,您就會得到一個正常的 function 指針,它可以很好地與 std::bind/std::function/etc 配合使用。

可以在 此處找到允許上下文的完整列表。

一點語法糖

如果你經常需要使用模板函數的重載,比如 std::bind,你可以采用 QT 中QOverload class 中使用的方法,它為此提供了一個方便和干凈的接口。 它僅適用於開箱即用的重載成員函數,但也可以輕松擴展為非成員函數。

這是 QT 文檔中的一個簡短演示:

struct Foo {
        void overloadedFunction();
        void overloadedFunction(int, const QString &);
    };
    ... qOverload<>(&Foo::overloadedFunction)
    ... qOverload<int, const QString &>(&Foo::overloadedFunction)

與static_cast相比,你不需要顯式指定返回類型,因為不可能有兩個參數相同但返回類型不同的函數,也沒有class name

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM