Я пытаюсь написать шаблонный помощник, который позволяет мне проверять, соответствует ли набор типов типам членов структуры. Пока что я написал это -
#include <iostream>
#include <functional>
struct foo {
int field1;
int field2;
};
template <typename...T, std::size_t ...indices >
constexpr bool construct (std::index_sequence<indices...>) {
foo s = {std::get<indices>(std::tuple<T...>())...};
return true;
}
template<typename...T>
static bool allowed(int) {
construct<T...>(std::index_sequence_for<T...>());
return true;
}
template<typename...T>
static bool allowed(long) {
return false;
}
int main() {
std::cout << allowed<int, int, int>(0);
return 0;
}
Здесь, очевидно, вызов allowed<int, int, int>
недопустим, потому что конструкция не может быть вызвана (foo имеет 2 члена, и он инициализируется с 3). Но есть другая реализация allow, которая принимает long
в качестве аргумента. Начиная с SFINAE, разве компилятор не должен просто соответствовать реализации второго шаблона allow и возвращать false
? Но вместо этого он выдает ошибку -
ошибка: слишком много инициализаторов для 'foo'
foo s = {std::get<indices>(std::tuple<T...>())...};
Если я просто закомментирую Первая реализация разрешена, все слова в порядке, и я получаю ложное. Я запутался в том, как замена шаблона взаимодействует с неявными приведениями и перегрузкой функций. Если это не разрешено, есть ли способ добиться того же эффекта?