在 C++17 中的每个实例化时生成一个新类型



请考虑以下代码:

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

在 C++17 中使用奇怪的技巧是否有可能让foobar是不同类型的?

真正的答案:不。如果你想要不同的类型,写不同的类型。整个概念是疯狂的。


玩具答案,当然。首先,您可以宏化类型:

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

或者,由于我们厚颜无耻,您可以将两个名称foobar都宏化:

template <int N>
struct object {
object(int ) { }
};
#define foo(x) <0> foo(x)
#define bar(x) <1> bar(x)

或者,也许只是其中之一:

template <class T>
struct object {
object(T ) { }
};
#define foo(x) <double> foo(x)

或者,您可以使用有状态元编程来破解不同的值。这适用于 gcc,但不适用于 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 ) { }
};

最新更新