I have read the std::is_constant_evaluated()
definition, but I still not sure why (1) is not working with the latest GCC: error: 'x' is not a constant expression
template<auto v>
struct s
{};
constexpr void f(int x)
{
if (std::is_constant_evaluated())
{
// constexpr int z=x; (1)
// s<x> a; (2)
}
}
int main(int argc, char* argv[])
{
f(4);
//f(argc);
return 0;
}
- By the standard, should that work?
- Or just the GCC implementation is buggy?
- Somehow can I achieve the expected behavior? Which is basically:
With branching on std::is_constant_evaluated()
- if it is true: the code can use variables as constexpr (like (2))
- if it is false: the code use variables as non-constexpr
UPDATE
Can I 'transport' the constexpr-essiveness information into a function? Basically to decide in f()
that it was call with constexpr
x or not.
UPDATE A more complex example about what I would like to achieve: this sample should stringify the parameter in compile time if possible.
template<auto v>
struct dummy_stringify
{
static constexpr auto str=v==4 ? "4" : "31"; // this is just an example; imagine here a much more complex logic
};
constexpr void f(int x)
{
if (std::is_constant_evaluated())
{
std::puts("A compile time calculation:");
//std::puts(dummy_stringify<x>::str);
} else
{
std::cout<<"A runtime calculation:"<<std::endl;
std::cout<<x<<std::endl;
}
}
int main(int argc, char* argv[])
{
f(4);
f(argc);
return 0;
}