如何检测模板是否为别名模板
How can I detect whether a template is an alias template?
给定一个"正常"模板:
template<typename> struct Normal;
和别名模板:
template<typename>
using Alias = void;
当作为模板模板参数给出时,我如何区分这两者?
因此,理想情况下,我希望编译以下内容:
int main() {
static_assert( is_alias_template<Alias>::value, "");
static_assert(! is_alias_template<Normal>::value, "");
}
一种可能的方法是利用它:
在推导模板模板参数时,从不通过模板参数推导来推导别名模板。
http://en.cppreference.com/w/cpp/language/type_alias
因此,具有类似
template<
typename T,
template<typename...> class Template
>
struct instantiated_from
: std::false_type {};
template<
template<typename...> class Template,
typename... Arguments
>
struct instantiated_from<Template<Arguments...>, Template>
: std::true_type {};
我们可以确定,当我们将Alias<int>
作为第一个模板参数传递,Alias
作为第二个模板参数传递时,编译器不会选择专用化。这立即为我们提供了:
template<
template<typename...> class Template,
typename... Args
>
struct is_alias_template
: std::integral_constant<
bool,
! instantiated_from<Template<Args...>, Template>::value
>
{};
有了这个,我们可以 - 给定一些合适的模板参数 - 检测模板是否是别名模板:
int main() {
static_assert( is_alias_template<Alias, int>::value, "");
static_assert(! is_alias_template<Normal, int>::value, "");
static_assert( is_alias_template<Alias, Alias<int>>::value, "");
static_assert( is_alias_template<Alias, Normal<int>>::value, "");
static_assert(! is_alias_template<Normal, Alias<int>>::value, "");
static_assert(! is_alias_template<Normal, Normal<int>>::value, "");
}
这里的主要缺点当然是需要知道一组合适的模板参数。仅猜测(或使用int
(不适用于例如具有固定数量(>1(模板参数的模板。
此外,这不适用于具有非类型(或模板(模板参数的(别名或非别名(模板。
相关文章:
- std::shared_ptr 使用别名构造函数,是否可以检索初始指针值?
- 是否可以为 std::cout 创建别名?
- 严格的别名是否会阻止您通过其他类型写入 char 数组?
- 强制转换为不相关的引用类型是否违反严格的别名规则?
- 是否可以为模板类的模板函数成员设置别名?
- 使用容器中元素的别名删除带有 std::list::remove 的元素是否正确?
- 将空基类优化对象强制转换为另一种类型是否会破坏严格的别名?
- 别名漏洞是否适用于签名字符?
- 将结构别名为其第一个成员是否严格违反别名
- 是否可以将引用类型别名与指针运算符一起使用来声明对指针的引用?
- 如何检测模板是否为别名模板
- C++20 中的严格别名规则是否允许标准 c++ unicode 字符和下划线类型之间"reinterpret
- 严格别名规则是否适用于跨函数调用
- 链表的这个别名运算符是否会产生深度复制
- 如何检查函数中的模板参数是否与给定类型别名的专用化匹配
- c++11 严格别名规则是否允许通过 char *、char(&)[N],甚至 std::array<char、N> 和 -fstrict-aliasing -Wstrict-aliasi
- 命名空间别名是否会更改链接?
- 类型别名是否用作函数类型参数的一部分,是函数签名的一部分
- 已签名/未签名的别名规则是否按预期工作
- "size_t"是否始终是"vector<int>::size_type"或任何其他容器类型的别名?