3

So I've written a basic type tagging structure:

struct TypeTag
{
    inline static size_t counter = 0;

    template<typename T>
    static size_t get()
    {
        static size_t value = counter++;
        return value;
    }
};

class c1 {};
class c2 {};
class c3 {};
class c4 {};

int main()
{
    std::cout << "c1: " << TypeTag::get<c1>() << '\n';
    std::cout << "c2: " << TypeTag::get<c2>() << '\n';
    std::cout << "c3: " << TypeTag::get<c3>() << '\n';
    std::cout << "c4: " << TypeTag::get<c4>() << '\n';

    std::cout << "\n================================\n\n";

    std::cout << "c1: " << TypeTag::get<c1>() << '\n';
    std::cout << "c2: " << TypeTag::get<c2>() << '\n';
    std::cout << "c3: " << TypeTag::get<c3>() << '\n';
    std::cout << "c4: " << TypeTag::get<c4>() << '\n';
    
    return 0;
}

Output:

c1: 0
c2: 1
c3: 2
c4: 3

================================

c1: 0
c2: 1
c3: 2
c4: 3

This will associate a type to a value.

Here's a working example of it: https://godbolt.org/z/9rqK6Pasz

Suppose we know the value at compile time: template <size_t value>; is there any way to do the opposite? Is there any way to associate a variable value to a type?

template <size_t value>
struct TypeFrom
{
    using type = ... // SOMETHING HERE 
};
bibanac
  • 135
  • 7

1 Answers1

2

As shown, this is not possible for some fairly fundamental reasons: C++ simply does not work this way.

The value of TypeTag::get<T> is known only at runtime. The value for a given T depends on the order of the first call to a template instance for this particular T relative to first calls for other types. It's entirely possible that each time the program runs the same types get different TypeTags. This is fundamental to C++: a statically-scoped object is constructed the first time its scope gets entered. The fact that the scope is generated from a template is immaterial. Effectively counter++ gets evaluated, to initialize the static size_t value the first time its get() gets called.

So, when all is said and done, a particular TypeTag::get<T> value is known only at runtime.

But templates parameters (such as the size_t n in ValueType<n>) must be known at compile time. This is fundamental to C++. The End.

Sam Varshavchik
  • 114,536
  • 5
  • 94
  • 148
  • 1
    But if we now know the value from `template ` at compile time; is it still not possible? – bibanac Jul 14 '23 at 00:19
  • 2
    If `T` is `int`, for example, you don't know what it's `value` is 2, for example, at compile time. Because the next time you run this program it can be 4. Or 42. So, how do you believe you can figure out what type `2`, or `4`, or `42` is, at compile time, when the actual types that correspond to those values will only be known at runtime? – Sam Varshavchik Jul 14 '23 at 00:51
  • 1
    @bibanac If you really know the value **and the complete set of possible types** at compile time, instead of adding the types dynamically at runtime as shown in your code, then you can just use `std::variant_alternative_t` or `std::tuple_element_t`, no need to write your class. Otherwise, it is impossble, as this answer correctly indicates. – Weijun Zhou Jul 14 '23 at 02:09