Я пытаюсь использовать следующий код, чтобы проверить, создан ли шаблон в неоцененном контексте:
#include "foo.h"
template <typename T = int>
constexpr auto f(int)
// from declaration, foo(std::declval<T>()) is allowed.
// Even if definition would produce errors if instantiated
-> decltype(foo(std::declval<T>()), void(), 42)
{
return 42;
}
static_assert(f(0) == 42);
с foo
в качестве функции шаблона: (без ошибок)
template <typename ...Ts>
void foo(Ts... args)
{
static_assert(sizeof...(Ts) == 42, "!");
((args += ""), ...);
}
Демо
с foo
в качестве обычного функтора: (без ошибок)
struct Foo
{
template <typename ...Ts>
void operator ()(Ts... args) const
{
static_assert(sizeof...(args) == 42, "!");
((args += ""), ...);
}
} foo;
Демо
Но foo
как лямбда: (Ошибка)
auto foo = [](auto... args)
{
static_assert(sizeof...(args) == 42, "!"); // Triggers
((args += ""), ...); // spotted as invalid: int += const char*
};
Демо
Это нормально, что создается экземпляр operator()
lamdba?
gcc / clang ведут себя так же.