my_fun可以如使用SFINAE以下來實現。
namespace details{
struct A{};
struct B:A{};
// A container will have a begin and an end. Also make it first prerference
template<typename T>
auto my_fun_impl(T const & obj, B *) -> decltype(obj.begin(),obj.end(),void())
{
std::cout<<"Container\n";
}
// Default choice
template<typename T>
auto my_fun_impl(T const & obj,A*) -> void
{
std::cout<<"Other than Container\n";
}
}
template<typename T>
auto my_fun(T const & obj) -> void
{
details::my_fun_impl(obj,static_cast<details::B *>(0));
}
注意這裏傳遞一個Base
或Derived
類指針,否則編譯器會抱怨不明確的功能定義。
編譯器將嘗試匹配my_fun_impl
的確切簽名與B pointer
,它將在容器的情況下成功。因爲一個容器將有begin()和end(),預計在尾隨返回類型中。
在非容器類型的情況下,第一選項將不匹配。而且我們知道一個Base
類指針可以容納派生類對象,所以默認匹配會成功。
及後續測試代碼的輸出
int main()
{
my_fun(std::vector<int>{1,2,3});
my_fun(1);
}
將
Container
Other than Container
Demo on coliru
除了看起來像一個糟糕的設計,我建議你看一下在設計相反,你可以使用[ *型性狀*](http://en.cppreference.com/w/cpp/types#Type_traits_.28since_C.2B.2B11.29)。您可能需要實現適合您的特定類型特徵,例如'is_container'。 –
'std :: string'當然是一個字符的容器,所以這個問題假設了一個錯誤的二分法。 – MSalters