-3

I have written some type conversion operators which only make sense in the context of a subset of types.

An example is below

explicit virtual operator DataId<float>() const
{
    static_assert(std::is_same_v<T, DataId<float>>, "std::is_same_v<T, DataId<float>>");
    return data; // T data
}

This class contains an object of type T=DataId<U>, where U=float, int, double, std::string.

static_assert seems to demand that the argument passed to it to create the error message is a const char*.

Is there a way to print the type of T in the message?

I tried, but failed, with this attempt:

constexpr auto message(
    (std::string("std::is_same_v<T=") + typeid(T).name() + ", DataId<float>>").c_str()
);
static_assert<..., message>;
Uwe Keim
  • 39,551
  • 56
  • 175
  • 291
FreelanceConsultant
  • 13,167
  • 27
  • 115
  • 225
  • See [Is it possible to print a variable's type in standard C++?](https://stackoverflow.com/questions/81870/is-it-possible-to-print-a-variables-type-in-standard-c) and [How to Identify type of a variable](https://stackoverflow.com/questions/36948545/how-to-identify-type-of-a-variable) – Jason Nov 19 '22 at 14:17
  • @JasonLiam How does that help? Am I missing something obvious? – FreelanceConsultant Nov 19 '22 at 14:20
  • The linked question just says "this is not possible". Is that really true? Even with modern C++ there really is no way to print type information as part of a `static_assert`? – FreelanceConsultant Nov 19 '22 at 14:21
  • See also [adding string literal to static_assert](https://stackoverflow.com/questions/5604290/adding-string-literal-to-static-assert) – Jason Nov 19 '22 at 14:21
  • 2
    No, there is no way. The answer hasn't changed. – StoryTeller - Unslander Monica Nov 19 '22 at 14:22
  • I think you can wrap it inside a template and compiler would tell you the instantiated parameter. – apple apple Nov 19 '22 at 14:28
  • something like this https://godbolt.org/z/7aP35vsb6 – apple apple Nov 19 '22 at 14:31
  • Printing types in error contexts, like the one generated from a failing static assert, is doable by wrapping them in an incomplete type. I made [this demo](http://coliru.stacked-crooked.com/a/f4abb26e340897a0) to showcase a class `tc` (typed condition) where you can provide a condition and a type to print, then the whole thing can be passed to a `static_assert` and the compilation error contains the info you want. In case you "need" the type name to interleave with a string message .. that's a different story. – Nikos Athanasiou Nov 19 '22 at 15:36

2 Answers2

0

the message need to be a string literal, so you cannot do it.


Newer gcc/clang already output the types for std::is_same as well. (gcc 11/clang 8)


For compilers that doesn't do it and make it harder to get the real types.

A possible workaround is wrap it inside a template and make it a hard error, then compiler would probably tell you the instantiated types.

template<typename T, typename U>
consteval void assert_same(){
    static_assert(
        std::is_same_v<T, U>
    );
}

// usage:
template<typename U>
struct X{
    using T = std::vector<U>;
    void foo(){
        assert_same<T,float>();
    }
};

would result in a report of

In instantiation of 'consteval void assert_same() [with T = XXX; U = XXX]':

...

error: static assertion failed

https://godbolt.org/z/Y7TEhM51f


apple apple
  • 10,292
  • 2
  • 16
  • 36
0

According to https://en.cppreference.com/w/cpp/language/static_assert :

Since message has to be a string literal, it cannot contain dynamic information or even a constant expression that is not a string literal itself. In particular, it cannot contain the name of the template type argument.

So if it's explicitly said that it can't contain the template name, I don't think it can be done.