【发布时间】:2021-12-15 15:18:30
【问题描述】:
我正在尝试从模板模板参数生成唯一 ID。我试过这个功能
inline size_t g_id = 1;
template<template<typename> typename T>
inline size_t GetID()
{
static size_t id = g_id++;
return id;
}
在使用别名模板之前它工作正常
template<template<typename> typename T>
inline void print()
{
std::cout << GetID<T>() << "\n";
}
template<typename T>
struct S {};
struct W1 { template<typename A> using type = S<A>; };
struct W2 { template<typename A> using type = S<A>; };
int main()
{
print<S>();
print<W1::type>();
print<W2::type>();
std::cin.get();
}
MSVC
1
2
3
叮当
1
2
3
海合会
1
1
1
这里有没有正确的编译器,或者某处有 UB?
更新
在阅读了 Davis Herring 的评论 CG1286 中链接的一些材料后,别名模板不需要与基础模板具有相同的模板名称。对我来说,这似乎是双向的,所以这里所有的编译器都兼容吗?
因此,我想出了一种不同的方法来从模板模板参数生成 ID,这应该可以避免这个问题,但有一些妥协。要求您使用 Tag 类型专门化模板并创建检索您的 ID 的静态方法。
实施
inline size_t g_id = 1;
template<typename T>
inline size_t GenerateID()
{
static size_t id = g_id++;
return id;
}
struct Tag {};
template<template<typename...> typename T, typename... Args, typename = decltype(sizeof(T<Args...>))>
inline size_t get_id_imp(int)
{
return T<Args...>::GetID();
}
template<template<typename...> typename T, typename... Args, std::enable_if_t<sizeof...(Args) < 16, bool> = true>//16 = max template args
inline size_t get_id_imp(...)
{
return get_id_imp<T, Args..., Tag>(0);
}
template<template<typename...> typename T, typename... Args, std::enable_if_t<sizeof...(Args) >= 16, bool > = true>
inline size_t get_id_imp(...)
{
return 0;
}
template<template<typename...> typename T>
inline size_t GetID()
{
return get_id_imp<T, Tag>(0);
}
使用
template<typename T>
struct X {};
template<> struct X<Tag> { static size_t GetID() { return GenerateID<X>(); } };
template<template<typename...> typename T>
inline void print()
{
std::cout << GetID<T>() << "\n";
}
【问题讨论】:
-
我不认为它符合重复的条件,但它是相同的错误recently encountered。
标签: c++ templates c++17 language-lawyer type-alias