您可以使用別名模板,將SFINAE出類型,而包含傳遞給您的專業如迭代器類型:
#include <vector>
#include <array>
template <class>
struct without_iterator { };
template <class T>
struct X {
static constexpr bool value = false;
};
template <class T, class...>
using typer = T;
template <class T>
struct X<typer<T, typename T::iterator>> {
static constexpr bool value = true;
};
int main() {
static_assert(X<std::vector<int>>::value, "!");
static_assert(X<std::array<int, 4>>::value, "!");
static_assert(!X<without_iterator<int>>::value, "!");
static_assert(!X<int>::value, "!");
}
其中X
是你的CPPUNIT_NS::assertion_traits
[live demo]
將它應用到您的解決方案:
template <class T, class...>
using typer = T;
namespace CPPUNIT_NS
{
template <class T> struct assertion_traits<typer<T, typename T::iterator>>
{
inline static bool equal(const T& left, const T& right)
{
return std::equal(left.begin(), left.end(), right.begin(), assertion_traits<decltype(*(left.begin()))>::equal);
}
inline static string toString(const T& vector)
// etc...
如果你想你也可以測試開始結束所有腦幹,使您的T肯定接口如預期。如果你願意,甚至可以使用test if T comes from std namespace(至少在某些有限的範圍內)。
編輯:
更安全的辦法是堅持:
template <template <class...> class V, class... Ts>
struct X<typer<V<Ts...>, typename V<Ts...>::iterator>> {
static constexpr bool value = true;
};
即使它不能應用於std::array
爲使用struct X<typer<T, typename T::iterator>>
可能不是由編譯器爲一體的專業化可以看出X
模板,但重新定義X
(example)...
@JayBazuzi - 你應該告訴我們通用的'assertion_traits';無論如何,從W.F .:看起來比我的好(或者,至少是比我的解決方案更好的基礎) – max66
這有很多幫助:'CPPUNIT_ASSERT_EQUAL'很滿意聲明。但是'std :: equal()'調用無法編譯。 –
http://cppunit.sourceforge.net/doc/1.8.0/struct_cpp_unit_1_1assertion__traits.html –