簡體   English   中英

條件運算符無法解析重載的成員函數指針

[英]Conditional operator can't resolve overloaded member function pointers

我在處理C ++中重載成員函數的指針時遇到了一個小問題。 以下代碼編譯正常:

class Foo {
public:
    float X() const;
    void X(const float x);
    float Y() const;
    void Y(const float y);
};

void (Foo::*func)(const float) = &Foo::X;

但是這不會編譯(編譯器抱怨重載是不明確的):

void (Foo::*func)(const float) = (someCondition ? &Foo::X : &Foo::Y);

大概這與編譯器分離出條件運算符的返回值和函數指針類型有關嗎? 我可以解決它,但我很想知道規范如何說這一切應該工作,因為它似乎有點不直觀,如果有一些方法可以解決它而不會回到5行if-then-else 。

我正在使用MSVC ++,如果這有任何區別。

謝謝!

從第13.4 / 1節(“重載功能的地址”,[over.over]):

在某些上下文中使用不帶參數的重載函數名稱解析為函數,指向函數的指針或指向來自重載集的特定函數的成員函數的指針。 函數模板名稱被認為是在這種上下文中命名一組重載函數。 選擇的函數是其類型與上下文中所需的目標類型匹配的函數。 目標可以是

  • 正在初始化的對象或引用(8.5,8.5.3),
  • 任務的左側(5.17),
  • 函數的參數(5.2.2),
  • 用戶定義的運算符的參數(13.5),
  • 函數,運算符函數或轉換的返回值(6.6.3),或
  • 顯式類型轉換(5.2.3,5.2.9,5.4)。

過載函數名稱可以以&運算符開頭。 如果沒有參數,則不應在除列出的上下文之外的上下文中使用重載的函數名稱。 [ 注意:忽略重載函數名稱周圍的任何多余括號(5.1)。 ]

您希望從上面的列表中選擇的目標是第一個,正在初始化的對象。 但是有一個條件運算符,條件運算符從它們的操作數確定它們的類型,而不是從任何目標類型。

由於顯式類型轉換包含在目標列表中,因此可以分別在條件表達式中類型轉換每個成員指針表達式。 我先做一個typedef:

typedef void (Foo::* float_func)(const float);
float_func func = (someCondition ? float_func(&Foo::X) : float_func(&Foo::Y));

例:

class Foo {
public:
    void X(float x) {}
    void Y(float y)  {}
    float X() const;
};
typedef void (Foo::*Fff)(float);
Fff func = &Foo::X;
Fff func2 = true ? (Fff)&Foo::X : (Fff)&Foo::Y;

int main(){
    return 0;
}

您需要立即轉換&Foo :: X以解決過載問題。 請注意,如果注釋掉重載的浮點X(),則不需要這樣做。

看起來編譯器不夠智能來推斷三元表達式所需的返回類型(這可能是一個錯誤)。

嘗試:

    void (Foo::*func1)(const float) = &Foo::X;
    void (Foo::*func2)(const float) = &Foo::Y;

    void (Foo::*func3)(const float) = (someCondition ? func1:func2);

問題是運算符trinary的結果類型由其參數決定。
在這種情況下,它無法確定結果類型,因為輸入類型具有多個選項。 直到三元運算符的類型被確定它將嘗試分配。

暫無
暫無

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

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