Установка i-го параметра в шаблоне

278
18 июня 2017, 17:31

Есть класс, у которого все параметры шаблона имеют значение по умолчанию:

template<class T1 = t1, ..., class Ti = ti, ..., class Tn = tn>
class A {
    // ...
};

Как установить значение для параметра Ti, а значения остальных параметров оставить по умолчанию?

A<Ti = int> a; // как-то так хотелось бы

UPD

Будет здорово, если удастся найти решение, которое позволит задавать произвольное количество аргументов, а остальные оставлять по умолчанию:

A<Ti = int, Tj = float, ...> a;
Answer 1

в качестве бредовой идеи, а вдруг кто-то вдохновится

#include <iostream>
#include <typeinfo>
template<typename T1 = int, typename T2 = int>
class sample {
    T1 x;
    T2 y;
};
template <std::size_t I, typename S>
auto sample_get() {
    if constexpr (I == 1) {
        return sample<S, int>();
    } else if constexpr (I == 2) {
        return sample<int, S>();
    }
}
int main() {
    auto x = sample_get<1, float>();
    std::cout << typeid(x).name() << std::endl;
    auto y = sample_get<2, double>();
    std::cout << typeid(y).name() << std::endl;
}
Answer 2

Есть одно решение, правда использует оно Boost.Hana. Удобства:

  • Расширяемость: можно добавлять в конец новые шаблонные параметры
  • Конструкция пишется один раз, нет смысла в куче usingов
  • Никакого overhead'а, доступ к параметрам остался, все проверки во время компиляции

На Ваш суд:

#include <boost/hana.hpp>
namespace hana = boost::hana;
template <class _Args = decltype(hana::tuple_t<int, float, double>)> // параметры по умолчанию - int, float, double
class BaseA {
public:
    using Args = _Args;
    template <size_t N> // для доступа к аргументам шаблона
    using Arg = typename decltype(+Args{}[hana::size_c<N>])::type;
};
template <class Type, size_t Pos> // тип, который хотим поменять, и его позиция
using fix_A_arg = BaseA<decltype(hana::insert(hana::remove_at(BaseA<>::Args{}, hana::size_c<Pos>), hana::size_c<Pos>, hana::type_c<Type>))>;
int main(int /*argc*/, char** /*argv*/) {    
    using A = BaseA<>;
    static_assert(std::is_same_v<A::Arg<0>, int>);
    static_assert(std::is_same_v<A::Arg<1>, float>);
    static_assert(std::is_same_v<A::Arg<2>, double>);
    using B = fix_A_arg<bool, 0>;
    static_assert(std::is_same_v<B::Arg<0>, bool>);
    static_assert(std::is_same_v<B::Arg<1>, float>);
    static_assert(std::is_same_v<B::Arg<2>, double>);
    using C = fix_A_arg<struct Foo, 1>;
    static_assert(std::is_same_v<C::Arg<0>, int>);
    static_assert(std::is_same_v<C::Arg<1>, struct Foo>);
    static_assert(std::is_same_v<C::Arg<2>, double>);
    return 0;
}

Онлайн-проверка

READ ALSO
Есть ли в Qt в QRegExp позиционные проверки?

Есть ли в Qt в QRegExp позиционные проверки?

Вот такие вот проверки:

370
Буфер обмена - C++ WinAPI

Буфер обмена - C++ WinAPI

Здравствуйте, помогите пожалуйста, нужно сделать программу, которая демонстрирует, передачу информации различных форматов(текст, графика)...

412
Использование __VA_ARGS__ в define если аргументов нет

Использование __VA_ARGS__ в define если аргументов нет

Например, есть код где всё уже определено :

265
Цикл внутри потока. С++

Цикл внутри потока. С++

Здравствуйте!

252