Проверьте признаки для всех аргументов шаблона переменной
Фон : Я создал следующий классC
чей конструктор должен взятьN
переменные типаB&
:
class A;
class B
{
A* getA();
};
template<size_t N>
class C
{
public:
template<typename... Args>
inline C(Args&... args) :
member{args.getA()...}
{}
private:
std::array<A*, N> member;
};
Проблема: моя проблема заключается в том, как ограничить вариационныеArgs
быть всем типомB
?
Мое частичное решение: Я хотел определить предикат как:
template <typename T, size_t N, typename... Args>
struct is_range_of :
std::true_type // if Args is N copies of T
std::false_type // otherwise
{};
И переопределите мой конструктор соответственно:
template <typename... Args,
typename = typename std::enable_if<is_range_of_<B, N, Args...>::value>::type
>
inline C(Args&... args);
Я видел возможное решение в этом посте:https://stackoverflow.com/a/11414631, который определяет общийcheck_all
предикат:
template <template<typename> class Trait, typename... Args>
struct check_all :
std::false_type
{};
template <template<typename> class Trait>
struct check_all<Trait> :
std::true_type
{};
template <template<typename> class Trait, typename T, typename... Args>
struct check_all<Trait, T, Args...> :
std::integral_constant<bool, Trait<T>::value && check_all<Trait, Args...>::value>
{};
Итак, я мог бы написать что-то вроде:
template <typename T, size_t N, typename... Args>
struct is_range_of :
std::integral_constant<bool,
sizeof...(Args) == N &&
check_all<Trait, Args...>::value
>
{};
Вопрос 1 : Я не знаю, как определитьTrait
потому что мне нужно как-то связатьstd::is_same
сB
в качестве первого аргумента. Есть ли какие-либо средства использования общегоcheck_all
в моем случае, или текущая грамматика C ++ несовместима?
Вопрос 2 : Мой конструктор также должен принимать производные классыB
(через ссылку наB
), это проблема для вывода аргумента шаблона? Я боюсь, что если я использую предикат вродеstd::is_base_of
Я получу разные экземпляры конструктора для каждого набора параметров, которые могут увеличить размер скомпилированного кода ...
Редактировать : Например, у меня естьB1
а такжеB2
что наследует отB
, Я звонюC<2>(b1, b1)
а такжеC<2>(b1, b2)
в моем коде, это создаст два экземпляра (изC<2>::C<B1, B1>
а такжеC<2>::C<B1, B2>
) Я хочу только случаиC<2>::C<B, B>
.