CTAD создает экземпляр другой специализации, когда указан явный аргумент.C++

Программы на C++. Форум разработчиков
Anonymous
 CTAD создает экземпляр другой специализации, когда указан явный аргумент.

Сообщение Anonymous »

https://godbolt.org/z/EoeGs3E3v
#ifdef WITH_CONCEPT
# include
# define CONCEPT std::same_as
#else
# define CONCEPT
#endif

template
//requires(sizeof...(Ns) > 0) // workaround
struct Foo {
static_assert(sizeof...(Ns) > 0);

static constexpr auto cnt = sizeof...(Ns);
static constexpr auto cnt0 = (0u + ... + (Ns == 0));

constexpr Foo() requires(cnt0 == 0) {}

constexpr explicit(cnt0 == 1)
Foo(CONCEPT auto...args)
requires(cnt0 > 0 && cnt0 == sizeof...(args))
{}
};

template void func() {}

int main() {
// This is okey, but would have same problem if `auto` is replaced with `Foo`
constexpr auto F = Foo{};

// Some compilers instantiate Foo which has hard error
func();
}

No WITH_CONCEPT WITH_CONCEPT
Clang ❎ ❎
GCC ❎ ✅
MSVC ✅ ✅

Что говорит об этом стандарт?
Изменить: Частично сокращено до Всегда ли построение NTTP происходит для CTAD, даже если значение типа этой специализации задано?

Вывод Clang:
:11:19: error: static assertion failed due to requirement 'sizeof...(Ns) > 0'
11 | static_assert(sizeof...(Ns) > 0);
| ^~~~~~~~~~~~~~~~~
:18:24: note: in instantiation of template class 'Foo' requested here
18 | constexpr explicit(cnt0 == 1)
| ^
:31:10: note: while substituting deduced template arguments into function template '' [with Ns = (no value), args:auto = ]
31 | func();
| ^
:31:5: note: while substituting explicitly-specified template arguments into function template 'func'
31 | func();
| ^
:11:33: note: expression evaluates to '0 > 0'
11 | static_assert(sizeof...(Ns) > 0);
| ~~~~~~~~~~~~~~^~~
1 error generated.


Подробнее здесь: https://stackoverflow.com/questions/790 ... t-is-given

Вернуться в «C++»