我正試圖解決一個相對容易的涉及SFINAE的激發式。 我的目標是為特定型別的T找到最佳的排序方法。 對我來說有3種情況:
1.型別T支持`sort`函式
2.型別T支持范圍,即。有開始和結束函式 (讓不包括在這點的可比性)。
3.型別T是不可排序(不支持范圍,并且不有排序功能)
所以我寫了基本的模板多載并試圖從SFINAE中獲益
struct HaveSort { char c; };
struct HaveRange { char c; HaveSort s; };
struct HaveNone { char c; HaveRange r; };
template<typename T>
HaveSort test_sort(decltype(&T::sort), decltype(&T::sort)>;
template<typename T>
HaveRange test_sort(decltype(&T::begin), decltype(& T::end))。
template<typename T>
HaveNone test_sort(...)。
template<typename T, int N>
struct sort_helper。
template<typename T>
struct sort_helper<T, sizeof(HaveSort)>
{
static void fsort(T& x)
{
std::cout << "Type" << typeid(x)。 name() << " supports sort" << std::endl;
x.sort()。
}
};
template<typename T>
struct sort_helper<T, sizeof(HaveRange)>
{
static void fsort(T& x)
{
std::cout << "Type" << typeid(x)。 name() << " supports range" << std::endl;
std::sort(x.begin(), x.end() 。)
}
};
template<typename T>
struct sort_helper<T, sizeof(HaveNone)>
{
static void fsort(T& x)
{
std::cout << "Type" << typeid(x)。 name() << " supports nothing" << std::endl;
}
};
template<typename T>
void fast_sort(T& x)
{
sort_helper<T, sizeof(test_sort<T>(NULL, NULL))> 。 :fsort(x)。
}
class A {};
class B { void sort(){}. };
int main()
{
static_assert(sizeof(HaveSort) != sizeof(HaveRange), "尋找其他方法來處理 HaveSort 和 HaveRange
"/span>)。)
static_assert(sizeof(HaveRange)!= sizeof(HaveNone), "找到其他方法來處理HaveRange和HaveNone
")。)
std::vector<int> V{ 1,9, 5, 3 }。
A a;
B b;
fast_sort(V)。
fast_sort(a);
fast_sort(b)。
這樣就可以輸出
Type class std: 。 vector<int,class std::allocator<int> > 不支持任何東西
型別class A不支持任何東西
型別class B 不支持任何東西
對于所有三個類--vector<int>,A,B.
有沒有人知道為什么SFINAE在這里沒有接收到正確的多載? 謝謝。
uj5u.com熱心網友回復:
事實上,SFINAE適用于你的所有型別:
A沒有sort()/begin()/end()B沒有begin()/end()并且沒有publicsort()。
std::vector<int>沒有sort(),并且&std::vector<int>:begin(類似于end)是模糊的,因為有幾個多載(const和非const方法)。
我會這樣做:
template <std:: size_t N> struct overload_priority : overload_priority<N - 1> {};
template <> struct overload_priority<0> {}; // lowest priority >。
template<typename T>
auto fsort(T& x, overload_priority< 2>) -> decltype(x. sort(), void())
{
std::cout << "Type" << typeid(x)。 name() << " supports sort" << std::endl;
x.sort()。
}
template<typename T>
auto fsort(T& x, overload_priority< 1>) -> decltype(std: :sort(x. begin(), x.end()), void())
{
std::cout << "Type" << typeid(x)。 name() << " supports range" << std::endl;
std::sort(x.begin(), x.end() 。)
}
template<typename T>
void fsort(T& x, overload_priority<0> )
{
std::cout << "Type" << typeid(x)。 name() << " supports nothing" << std::endl;
}
template<typename T>
void fast_sort(T& x)
{
fsort(x, overload_priority<5>{}); // big enough
}
uj5u.com熱心網友回復:
你的SFINAE失敗的原因:
成員函式sort()是private
&T::begin有多個多載,所以獲取其地址失敗。
我將使用bools和一些SFINAE幫助器來代替獲取地址和比較大小。
template<class T>
struct has_sort { //check if T has a (public) member function called sort()
template< class> static auto Test(. ...) -> std::false_type。
template<class TT>
static auto Test(int) ->
decltype( std::declval<TT&>().sort(), std::true_type() ) ;
static constexpr bool value = decltype(Test< T>(0))。 :值。
};
template<class T> inline static constexpr bool has_sort_v = has_sort<T> 。 :值。
template<class T>
struct has_range { // check if T supports `std::begin` and `std::end`.
template< class> static auto Test(. ...) -> std::false_type。
template<class TT>
static auto Test(int) ->
decltype( std::begin(std::declval<TT&>( ))。
std::end(std::declval<TT&>())。
std::true_type() )。
static constexpr bool value = decltype(Test< T>(0))。 :值。
};
template<class T> inline static constexpr bool has_range_v = has_range<T> 。 :值。
你的fast_sort函式可以是這樣的:
#include <algorithm>
#include <iostream>
#include <vector>
template<typename T>
void fast_sort(T& x) {
if constexpr(has_sort_v<T>) {
std::cout << "has_sort
"。
x.sort()。
} else if constexpr(has_range_v< T> ) {
std::cout << "has_range
"。
std::sort(std::begin(x), std::end(x))
} else {
std::cout << "bohoo
"。
}
}
class A {};
class B { public: void sort(){}。}; //note: sort() made public
int main() {
std::vector<int> V{ 1,9,5,3 };
A a;
B b;
fast_sort(V)。
fast_sort(a)。
fast_sort(b)。
輸出:
has_range
bohoo
有排序
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/316120.html
標籤:
下一篇:將自定義結構鑄成另一種模板型別
