1

Consider the following code:

template <class /* Weird Hack Here */>
struct object
{
    constexpr object(int value, /* Other Weird Hack */) noexcept;
};

int main() 
{
    object foo(1);
    object bar(1);
}

Would it be possible using weird tricks in C++17 to have foo and bar be different types?

Barry
  • 286,269
  • 29
  • 621
  • 977
Vincent
  • 57,703
  • 61
  • 205
  • 388
  • 3
    So if I put `object x(1);` inside a loop, do you expect an unbounded number of different types? – aschepler Jul 21 '17 at 23:18
  • 4
    Something similar to this is likely possible due to [stateful metaprogramming](https://stackoverflow.com/q/44267673/1896169), but will be prohibited in the future – Justin Jul 21 '17 at 23:41
  • Not C++17, but the metaclasses proposal would give you strong typedefs, which accomplishes nearly the same thing. – AndyG Jul 24 '17 at 13:55

1 Answers1

6

Real answer: No. If you want different types, write different types. The entire concept is insane.


Toy answer, sure. For one, you could macro out the type:

template <int N>
struct object {
    object(int ) { }
};

#define object object<__LINE__>

Or, since we're being cheeky, you could macro out both names foo and bar:

template <int N>
struct object {
    object(int ) { }
};

#define foo(x) <0> foo(x)
#define bar(x) <1> bar(x)

Or, maybe just one of them:

template <class T>
struct object {
    object(T ) { }
};

#define foo(x) <double> foo(x)

Or, you could use stateful metaprogramming to hack into different values. This works on gcc but not on clang:

template <int N>
struct flag
{
    friend constexpr int adl_flag(flag<N>);
    constexpr operator int() { return N; }
};

template <int N>
struct write
{
    friend constexpr int adl_flag(flag<N>) { return N; }
    static constexpr int value = N;
};

template <int N, int = adl_flag(flag<N>{})>
constexpr int read(int, flag<N>, int R = read(0, flag<N + 1>{}))
{
    return R;
}

template <int N>
constexpr int read(float, flag<N>)
{
    return N;
}

template <class T, int N=0, int R=write<read(0, flag<0>{})+N>::value>
struct object {
    object(T ) { }
};
Barry
  • 286,269
  • 29
  • 621
  • 977