2013-07-26 57 views
1

考慮下面的例子:解壓類作用域?

#include <iostream> 
#include <type_traits> 

template <typename Type> 
struct Something 
{ 
    template <typename OtherType> 
    static constexpr bool same() 
    {return std::is_same<Type, OtherType>::value;} 
}; 

template <class Type> 
struct Example 
{ 
    static_assert(Type::template same<double>(), "ERROR"); 
}; 

int main() 
{ 
    Example<Something<double>> example; 
    return 0; 
} 

static_assert檢查通過執行same()功能傳遞的類型是否滿足某種條件。

現在考慮一個可以傳遞多個TypesExample

#include <iostream> 
#include <type_traits> 

template <typename Type> 
struct Something 
{ 
    template <typename OtherType> 
    static constexpr bool same() 
    {return std::is_same<Type, OtherType>::value;} 
}; 

template <class... Types> 
struct Example 
{ 
    static_assert(/* SOMETHING */, "ERROR"); 
}; 

int main() 
{ 
    Example<Something<double>> example; 
    return 0; 
} 

有一個工作的語法,而不是SOMETHING檢查條件是否對所有類型的驗證(沒有一堆的輔助功能:我知道可以用這種方式完成,但我想知道是否有其他方法(如使用簡單的拆包處理...)

+0

真的可以用一個參數包做的唯一的事情就是解開它作爲一組參數的功能。所以不,沒有幫手就不能這樣做 –

+0

@MooingDuck先生,爲什麼不回答? – luk32

+0

@ luk32:我當時有兩句話的野心,但沒有更多。我已經刷新了一個完整的答案。 –

回答

1

真的,您可以使用參數包做的唯一一件事就是將它解包爲一組參數到一個功能。所以不,沒有幫手就不能這樣做。

如果你允許幫助函數,有一千種方法可以做到。最明顯的是某種logical_and

template<class first, class ...rest> 
constexpr bool logical_and(first f, rest... r) 
{return bool(f) && logical_and(std::forward<rest>(r)...));} 
//       ^unpack the rest recursively^ 

template<class last> 
constexpr bool logical_and(last l) 
{return bool(l);} 

template <class... Types> 
struct Example 
{ 
    static_assert(logical_and(Something<double>::same<Types>()...), "ERROR"); 
    //      ^unpack the results to the function^ 
}; 

這是完全未經測試,並且可能不編譯原樣

0

您可以通過簡單的專業 template Example不使用輔助功能做。

如果在現實世界中Example是你 不想專門只爲一個可變 static_assert着想,那麼你可以封裝在其自己的模板特一個可變static_assert ,有你的現實世界中類的類 繼承相應的實例化。這裏有一個例子 只是專門Example

#include <iostream> 
#include <type_traits> 

template <typename Type> 
struct Something 
{ 
    template <typename OtherType> 
    static constexpr bool same() 
    {return std::is_same<Type, OtherType>::value;} 
}; 

template<class ...Types> 
struct Example; 

template<> 
struct Example<>{}; 

template<class T> 
struct Example<T> 
{ 
    static_assert(T::template same<double>(), "ERROR"); 
}; 

template<class First, class ...Rest> 
struct Example<First,Rest...> : Example<Rest...> 
{ 
    static_assert(First::template same<double>(), "ERROR"); 
}; 

int main() 
{ 
    Example<Something<double>> example0; // OK 
    Example<Something<double>,Something<double>> example1; // OK 
    Example<Something<int>> example2; // Error 
    Example<Something<double>,Something<int>> example3; // Error 
    Example<Something<double>,Something<double>,Something<int>> example4; // Error 
    Example<Something<double>,Something<int>,Something<double>> example5; // Error 
    return 0; 
}