The whole bunch of "stateful" metaprogramming can be achieved by forcing template reevaluation. Here I don't want to discuss whether one should or should not use or depend on it. But since C++20 has allowed usage of lambdas in unevaluated contexts, I guess the Pandora's Box is now widely open.
The following code now provides expected results, because _is_complete
is now "reevaluated" on each new invocation (technically speaking, old specializations never change, only new ones are introduced).
https://godbolt.org/z/5zv884xvE
#include <cstddef>
#include <type_traits>
template <typename T, auto, typename = void>
struct _is_complete : std::false_type {};
template <typename T, auto A>
struct _is_complete<T, A, std::void_t<decltype(sizeof(T))>> : std::true_type {};
template <typename T, auto A = []{}>
constexpr auto is_complete() noexcept {
return _is_complete<T, A>{};
}
#include <iostream>
int main() {
std::cout << std::boolalpha;
struct incomplete;
std::cout << is_complete<incomplete>() << '\n'; // false
struct incomplete{};
std::cout << is_complete<incomplete>() << '\n'; // true
return 0;
}
This particular code is closelly related to How to write is_complete
template?, but I am more interested in possibility of forcing template reevaluation in general prior to C++20's lambdas.
Please, do not suggest using any kind of macros like __COUNTER__
since it would be useless within a template's declaration.
is_complete
so ODR is not broken. – Stelu__COUNTER__
or__LINE__
if you change the template a little to take asize_t
parameter and wrap it in a macro: #55342359 – Easterneris_complete<T>()
. – Rheumatisminline
legally allows ODR violation. That is a usefull detail, but the question's topic is somewhat different. – Rheumatismtemplate <typename T> constexpr auto foo();
(which has different implementations based onT
) and instantiate it multiple times with multiple unique user-defined types? Please, correct me if I am wrong, but as I know, each new lambda has a unique type. – Rheumatismauto A = []{}
defaulted parameter. If this expression is not required by the standard to be evaluated each time with the effects of creating "new lambda", I will agree with your point. But until now I have seen several answers like https://mcmap.net/q/20768/-does-c-support-compile-time-counters and behavior that suggests observable effects of creating new lambda object for defaulted parameter on each invocation. – Rheumatism