[英]Class template parameter pack expansion for constructors
我想創建一個類模板RestrictedInteger
,它只能用編譯時已知的某些值構造。 這就是我手動完成的方法:
// Wrapper
template<int... Is> using IntList = std::integer_sequence<int, Is...>;
// This is my class
template<class intList> class RestrictedInteger;
template<int I1>
class RestrictedInteger<IntList<I1>> {
const int _i;
public:
constexpr RestrictedInteger(std::integral_constant<int, I1>) : _i(I1) {}
};
//[...]
template<int I1, I2, I3>
class RestrictedInteger<IntList<I1, I2, I3>> {
const int _i;
public:
constexpr RestrictedInteger(std::integral_constant<int, I1>) : _i(I1) {}
constexpr RestrictedInteger(std::integral_constant<int, I2>) : _i(I2) {}
constexpr RestrictedInteger(std::integral_constant<int, I3>) : _i(I3) {}
};
//[...] (and so on)
當然,我想使用可變參數模板。 如果這只是合法的 :
template<int... Is>
class RestrictedInteger<IntList<Is...>> {
int _i;
public:
constexpr RestrictedInteger(std::integral_constant<int, Is>) : _i(Is) {}... // ERROR
}
因為我正在使用C ++ 17,我認為它會像這樣工作:
template<int... Is>
class RestrictedInteger<IntList<Is...>> {
int _i;
public:
template<int I>
constexpr RestrictedInteger(std::enable_if_t<...||(I==Is), std::integral_constant<int, I>>) : _i(I) {} // syntax error: '...' (Visual Stuio 2019)
};
但顯然不是。
有什么想法可以解決這個問題嗎?
如果編譯失敗是一個選項(您不需要編譯器來查找其他重載) - 您可以將static_assert
放在構造函數中:
#include <type_traits>
#include <utility>
template<int... Is> using IntList = std::integer_sequence<int, Is...>;
template<class intList> class RestrictedInteger;
template<int... Is>
class RestrictedInteger<IntList<Is...>> {
private:
const int _i;
public:
template <int I>
constexpr RestrictedInteger(std::integral_constant<int, I>) : _i(I)
{
static_assert(((I == Is) || ...), "Invalid value");
}
};
int main()
{
RestrictedInteger<IntList<1, 2, 3>> i = std::integral_constant<int, 3>();
RestrictedInteger<IntList<1, 2, 3>> ii = std::integral_constant<int, 6>(); // fails
}
或者使用std::enable_if
更詳細的解決方案:
#include <type_traits>
#include <utility>
template<int... Is> using IntList = std::integer_sequence<int, Is...>;
template<class intList> class RestrictedInteger;
template<int... Is>
class RestrictedInteger<IntList<Is...>> {
private:
const int _i;
public:
template <int I, typename std::enable_if_t<((I == Is) || ...)>* = nullptr>
constexpr RestrictedInteger(std::integral_constant<int, I>) : _i(I)
{
}
};
int main()
{
RestrictedInteger<IntList<1, 2, 3>> i = std::integral_constant<int, 3>();
RestrictedInteger<IntList<1, 2, 3>> ii = std::integral_constant<int, 6>(); // fails
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.