Я занимался поиском по two phase name lookup. Очень логичное объяснение показывает, что one of the main reasoning - это то, что следует за философией C++ ошибками лова как можно скорее.Создание некорректного нетемплифицированного метода шаблонного класса
Мой вопрос в том, почему эта философия не придерживается не-шаблонных методов. Вместо того, чтобы проверять, когда и когда вызывается метод, почему бы не проверить все не templated методы в фазе 2 при создании шаблона класса?
т.д .:
template <class T>
struct X {
auto foo() // non-templated (important)
{
T t{};
return t.non_existing();
}
};
int main()
{
X<int> x; // (1) this compiles OK.
// somewhere is a galaxy far far away,
// maybe deep inside some unrelated code
x.foo(); // (2) the error is here
}
Если вы никогда не писать (2) программа компилируется и работает без каких-либо проблем, хотя foo
является незаконным для реализованного X<int>
.
Я думаю, что строка (1) должна генерировать ошибку, независимо от того, когда вы когда-либо звоните foo
или нет.
При написании шаблонных классов это может пропустить пролом трещины, пока вы, наконец, не назовете этот проблемный метод (2), вместо получения ошибки при создании шаблона (1).
Также проверка работоспособности: является ли код действительным, если я создаю экземпляр X<int>
(1), но никогда не звоню X<int>::foo
(2)? Или это что-то вроде «плохо сформированного, никакой диагностики не требуется»? Если последнее, то это еще больше причин, чтобы поймать ошибку раньше.
Проверка работоспособности: код (1) действителен. Почему: Представьте себе создание конструктора копирования для 'std :: vector', если вам нужно было отключить его для непечатаемых 'T'. Dtto для 'push_back (const T &)' и т. Д. –
Angew
@Angew Я представил себе, что это управляется отключением методов с помощью SFINAE. – bolov