static_assert не оценивается в параметре шаблона - PullRequest
0 голосов
/ 04 января 2019

У меня есть этот код, чтобы определить, имеет ли тип шаблона foo ():

template <typename T, typename = void>
struct has_foo : std::false_type {};

template <typename T>
struct has_foo<T, std::void_t<decltype(std::declval<T&>().foo()) > > : std::true_type {};

template <typename T>
void has_foo_f(){
    static_assert(has_foo<T>::value, "Type does not have foo()."); 
}

Тогда у меня есть функция bar, которая принимает параметр шаблона с foo:

template<typename T, typename = decltype(has_foo_f<T>())>
void bar(){}

В основном файле у меня сбойный случай:

//Foo does not implement foo(). It should fail!
template<typename T>
class Foo{};

int main()
{
    has_foo_f<Foo<int>>(); //This line fail
    bar<Foo<int>>();       //This line does not fail
}

Когда я вызываю has_foo_f напрямую, компилятор выдает мне статическую ошибку подтверждения, которая является правильной. Однако когда я вызываю bar<Foo<int>>, компилятор успешно скомпилировал его без ошибок.

Почему это происходит? Почему static_assert не оценивается? Я понимаю, что decltype не нужно оценивать static_assert для получения информации о типе, но не static_assert всегда оценивается во время компиляции?

1 Ответ

0 голосов
/ 05 января 2019

Операнд decltype не оценивается и, следовательно, не требует, чтобы определение функции существовало (или возвращаемый тип был завершен), в то время как шаблон функции создается, когда на специализацию ссылаются в контексте, который требует определения функции для существования. Так что вам нужно создать экземпляр шаблона функции для проверки внутри тела функции:

template<typename T, auto Dummy = &has_foo_f<T>>
void bar(){}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...