我想根據給定的類型製作std::uniform_*_distribution
的特性。例如:使用enable_if與is_integral來製作分配特性
distribution_traits<float>::type int_dist;
我試過以下方法,但沒有一個編譯,我不知道爲什麼。
實現1
使用std::enable_if
與typedef
S:
template <typename T>
struct distribution_traits {
using type = typename std::enable_if<std::is_integral<T>::value, std::uniform_int_distribution<T>>::type;
using type = typename std::enable_if<std::is_floating_point<T>::value, std::uniform_real_distribution<T>>::type;
};
鏘3.4抱怨:
dist_traits.cpp:7:9: error: redefinition of 'type'
using type = typename std::enable_if<std::is_floating_point<T>::value, std::uniform_real_distribution<T>>::type;
^
dist_traits.cpp:6:9: note: previous definition is here
using type = typename std::enable_if<std::is_integral<T>::value, std::uniform_int_distribution<T>>::type;
^
dist_traits.cpp:6:40: error: no type named 'type' in 'std::enable_if<false, std::uniform_int_distribution<float> >'; 'enable_if' cannot be used to
disable this declaration
using type = typename std::enable_if<std::is_integral<T>::value, std::uniform_int_distribution<T>>::type;
^~~~~~~~~~~~~~~~~~~~~~~~~~
dist_traits.cpp:28:3: note: in instantiation of template class 'distribution_traits<float>' requested here
distribution_traits<float>::type int_dist;
^
2 errors generated.
實現2
使用enable_if
作爲類模板參數:
template <typename T, typename distribution_t = void>
struct distribution_traits;
template <typename T>
struct distribution_traits<
T, typename std::enable_if<std::is_integral<T>::value,
std::uniform_int_distribution<T> >::type > {
using type = std::uniform_int_distribution<T>;
};
template <typename T>
struct distribution_traits<
T, typename std::enable_if<std::is_floating_point<T>::value,
std::uniform_real_distribution<T> >::type > {
using type = std::uniform_real_distribution<T>;
};
而且鏘抱怨
dist_traits.cpp:28:3: error: implicit instantiation of undefined template 'distribution_traits<float, void>'
distribution_traits<float>::type int_dist;
^
無論如何不能被MSVC++ 12.0編譯,並且錯誤消息是相似的。
任何人都可以請解釋我在用SFINAE做什麼錯?謝謝!
對於那些誰是好奇的解決方案,下面是編譯一個:
template <typename T>
auto dist() -> typename std::enable_if<std::is_integral<T>::value, std::uniform_int_distribution<T>>::type;
template <typename T>
auto dist() -> typename std::enable_if<std::is_floating_point<T>::value, std::uniform_real_distribution<T>>::type;
template <typename T>
struct distribution_traits {
using type = decltype(dist<T>());
};
順便說一句,如果把dist
功能分爲distribution_traits
,編譯將失敗,錯誤:函數只不同的回報類型不能重載。 :(
改爲使用'std :: conditional'。 – Rapptz
@Rapptz謝謝!使用'std :: conditional',可以寫'使用type = typename std :: conditional :: type'。更好的代碼! –