4
我有一些代碼,很簡單,看起來有點像這樣:曖昧運營商<<選擇
#include <iostream>
#include <type_traits>
namespace X {
struct Foo {int x;};
struct Bar {int x;};
template <typename T , typename = typename std::enable_if<
std::is_same<decltype(T::x),int>::value
>::type>
std::ostream & operator<<(std::ostream & os, const T&) {
return os;
}
}
namespace Y {
struct Faa : X::Foo {int y;};
struct Baz {int x; int y;};
template <typename T , typename = typename std::enable_if<
std::is_same<decltype(T::x),int>::value &&
std::is_same<decltype(T::y),int>::value
>::type>
std::ostream & operator<<(std::ostream & os, const T&) {
return os;
}
}
int main() {
// Everything is ok
X::Foo x;
std::cout << x;
Y::Baz k;
std::cout << k;
// Problems..
Y::Faa y;
// std::cout << y; // <--operator is ambiguous
Y::operator<<(std::cout, y);
return 0;
}
有什麼辦法避免模棱兩可的運營商Y::Faa
,並具有手動指定Y::operator<<
?如果不是,爲什麼?
通過'enable_if'所施加的限制似乎很微弱(種類太多被允許)。你可以改進它們嗎?通過使用類型特質? – dyp 2014-09-23 14:27:16
在我的實際代碼中,我做了一個檢查各種成員方法存在的實際特徵,但這個想法是相同的。儘管如此,我認爲這還不算什麼問題。 – Svalorzen 2014-09-23 14:39:31
我寧願想像某種允許類型的列表;可以讓你「確定」哪些類型是(作爲)命名空間的直接成員。從這些,你可以選擇那些名爲'x'的成員。 – dyp 2014-09-23 14:43:37