簡體   English   中英

在轉換運算符不明確時選擇它們

[英]Selecting between conversion operators when they are ambiguous

我有兩種類型:

struct A { };
struct B { };

我有AB功能:

void fnA(A); // there are a lot of these functions
void fnB(B);

我有一個類型,可以轉換為AB

struct Foo {
    operator A();
    operator B();
};

所以我可以調用fnAfnB

fnA(Foo()); // fine
fnB(Foo());

現在,我有重載功能:

void fn(A);
void fn(B);

我無法用Foo調用它們,因為它含糊不清:

fn(Foo()); // ambiguous, which fn is called

在這種情況下,我想fn(A)被調用。

我可以添加第三個fn重載:

inline void fn(Foo foo) {
    fn(A(foo));
}

但我不喜歡這種方式,因為我有很多fn函數,而且我不想大大增加函數的數量(我有fn like函數遍布各處,這種改變會增加接口大小,這對我不好,因為我的界面已經很大了)。

另一個解決方案(如果沒有給出更好的替代方案,我會選擇)是為Foo使用繼承:

struct Foo: A {
    operator B();
};

在這種情況下,編譯器將選擇為fn(Foo())調用fn(A) fn(Foo()) ,它不再是模糊的。 但是我對這個解決方案並不滿意,因為Foo不是真正的A ,它是對繼承的誤用(另一方面,它是一個比前一個更好的解決方案,因為它解決了本地問題,我不知道必須添加許多不需要的fn函數)。

有沒有其他方法可以解決這個問題?

注意:我想要一個不涉及顯式轉換的解決方案,我希望能夠編寫fnA(Foo())fnB(Foo())fn(Foo())

一個花哨的模板包裝器怎么樣:

void fn_impl(A);
void fn_impl(B);

template<typename x_AB = A, typename x_Foo = Foo>
void fn(x_Foo && foo)
{
    return fn_impl(static_cast<x_AB>(foo));
}

fn(Foo()); // calls fn_impl(A);
fn<B>(Foo()); // calls fn_impl(B);

在線編譯器

我認為你可以通過使每個fn(B)重載一個模板來實現所需的行為:

void fn(A);

template<class = void>
void fn(B);

void bar()
{
    fn(Foo());
    fn(A());
    fn(B());
}

這會導致重載fn(A)在考慮模板化函數之前選擇fn(A) 必要的工作相當於在每個函數的每個B重載之前放置template<class = void> (如果聲明與定義分開,則將所有這些函數轉換為模板特化)。

演示

只需將Foo轉換為適當的類型:

#include <iostream>
#include <string>

struct A { };
struct B { };

struct Foo {
    operator A() { return A{}; };
    operator B() { return B{}; };
};

void fn(A) { std::cout << "A"; }
void fn(B) { std::cout << "B"; }

int main()
{
  fn(static_cast<A>(Foo()));
}

暫無
暫無

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

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