Есть вот такой код:
#include <tuple>
#include <vector>
using namespace std;
// (1)
template <typename L, typename R>
struct combine {
using type = tuple<L, R>;
};
// (2)
template <typename T>
struct combine<T, T> {
using type = vector<T>;
};
// (3)
template <typename ... Ts, typename T>
struct combine<tuple<Ts...>, T> {
using type = tuple<Ts..., T>;
};
// (4)
template <typename ... Ts, typename ... Us>
struct combine<tuple<Ts...>, tuple<Us...>> {
using type = tuple<Ts..., Us...>;
};
int main() {
using result = typename combine<tuple<int, char>, tuple<int, char>>::type;
return 0;
};
Как ни странно, компилятор начал ругаться на неопределённость:
main.cpp:26:72: error: ambiguous template instantiation for 'struct combine<std::tuple<int, char>, std::tuple<int, char> >'
26 | using result = typename combine<tuple<int, char>, tuple<int, char>>::type;
| ^~
main.cpp:11:8: note: candidates are: 'template<class T> struct combine<T, T> [with T = std::tuple<int, char>]'
11 | struct combine<T, T> {
| ^~~~~~~~~~~~~
main.cpp:16:8: note: 'template<class ... Ts, class T> struct combine<std::tuple<_Tps ...>, T> [with Ts = {int, char}; T = std::tuple<int, char>]'
16 | struct combine<tuple<Ts...>, T> {
Собственно вопрос в том, как помочь компилятору решить неоднозначность. Хотелось бы, чтобы правило (2) было в приоритете. Единственное, что пришло в голову - добавить в combine дополнительный аргумент Enable = void
для SFINAE и в правилах (3) и (4) прописать enable_if_t<!is_same_v<tuple<Ts...>, T>>
и enable_if_t<!is_same_v<tuple<Ts...>, tuple<Us...>>>
соответственно. Но по-моему это больше костыль, чем решение.
Нужно добавить такую специализацию:
template <typename ...P>
struct combine<std::tuple<P...>, std::tuple<P...>>
{
using type = std::vector<std::tuple<P...>>;
};
Но вообще, не нравится мне этот шаблон. Через пару месяцев вы сами-то вспомните, что combine
с двумя одинаковыми tuple
дает один результат, а с разными - другой?
Сначала нужно определить общий шаблон, а потом частные случаи(частичные специализации). И нужно помнить, что если шаблон класса имеет пакет параметров шаблона, он должен появиться в конце списка параметров шаблона.
// (1) с неизвестным количеством параметров (больше оодного)
template <typename T, typename ... Ts>
struct combine {
using type = tuple<Ts..., T>;
};
// (2) когда ровно два параметра
template <typename L, typename R>
struct combine<L, R> {
using type = tuple<L, R>;
};
// (3) с одним параметром
template <typename T>
struct combine<T, T> {
using type = vector<T>;
};
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Какое преимущество в билде от того, что header файлы будут включены вcpp, а не
подскажите пожалуйста Есть views и контроллер Как передать переменную в контроллер ,выполнить запрос и вернуть его в views К примеру по клике...
Получаю ответ в json от ajax запроса и пытаюсь вывести в <div class="writeinfo"></div>