簡體   English   中英

SFINAE無法避免模棱兩可的通話

[英]Ambiguous call not avoided by SFINAE

編譯這段代碼:

#include <iostream>


template <int N>
struct TestClass {
    template <int N2, typename std::enable_if<N2 == N, int>::type = 0>
    void doAction() { std::cout << "TestClass::doAction<" << N << ">();\n"; }
};

struct HostClass : public TestClass<1>, public TestClass<2> {
};


int main(int argc, const char * argv[]) {
    HostClass hostClass;

    hostClass.doAction<1>();
    hostClass.doAction<2>();

    return 0;
}

導致模棱兩可的調用錯誤,因為doAction都在TestClass<1>TestClass<2>父類中。

main.cpp:33:15:在不同類型的多個基類中找到成員“ doAction”

但是std::enable_if不會禁用這種歧義嗎?

編輯:

我認為造成這種歧義的真正原因與這個問題相同:

為什么同名但簽名不同的多重繼承函數不被視為重載函數?

如答案中所示,可以using關鍵字解決歧義:

#include <iostream>


template <int N>
struct TestClass {
    template <int N2, typename std::enable_if<N2 == N, int>::type = 0>
    void doAction() { std::cout << "TestClass::doAction<" << N << ">();\n"; }
};

struct HostClass : public TestClass<1>, public TestClass<2> {
    using TestClass<1>::doAction;
    using TestClass<2>::doAction;
};

int main(int argc, const char * argv[]) {
    HostClass hostClass;

    hostClass.doAction<1>();    // OK, compile
    hostClass.doAction<2>();    // OK, compile
    //hostClass.doAction<3>();  // OK, doesn't compile : "candidate template ignored: disabled by 'enable_if' [with N2 = 3]"

    return 0;
}

我不知道這是否是@skypjack答案的意思,但無論如何我還是選擇了它作為替代方法。

(讓我說)它將在替換后刪除兩個功能之一。
無論如何,首先,編譯器必須在調用doAction<1>時決定要使用哪個函數, 然后它可以繼續進行替換,並最終由於sfinae而放棄所選函數。
在調用時,它們都是有效的候選者,並且呼叫實際上是模棱兩可的。

請注意,正如@ Peregring-lk在注釋中所建議的, TestClass<1>::doActionTestClass<2>::doAction是放在不同名稱空間中的兩個不同函數,它們不是同一函數的重載。
這實際上是造成誤解的常見原因。


您可以輕松解決以下問題:

#include <iostream>

template <int N>
struct TestClass {
    void doAction() { std::cout << "TestClass::doAction<" << N << ">();\n"; }
};

struct HostClass : public TestClass<1>, public TestClass<2> {
    template<int N>
    void doAction() { return TestClass<N>::doAction(); }
};


int main(int argc, const char * argv[]) {
    HostClass hostClass;

    hostClass.doAction<1>();
    hostClass.doAction<2>();

    return 0;
}

暫無
暫無

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

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