[英]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.