在模板中使用模板别名,而不是模板 [英] Using a template alias instead of a template within a template

查看:117
本文介绍了在模板中使用模板别名,而不是模板的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

从上一个问题:

执行static_assert模板类型是另一个模板

Andy Prowl为我提供了这个代码允许我 static_assert 表示模板类型是另一个模板类型:

Andy Prowl provided me with this code that allows me to static_assert that a template type is another template type:

template<template<typename...> class TT, typename... Ts>
struct is_instantiation_of : public std::false_type { };

template<template<typename...> class TT, typename... Ts>
struct is_instantiation_of<TT, TT<Ts...>> : public std::true_type { };

template<typename T>
struct foo {};

template<typename FooType>
struct bar {
  static_assert(is_instantiation_of<foo,FooType>::value, ""); //success
};

int main(int,char**)
{
  bar<foo<int>> b; //success
  return 0;
}

这很好。

但是,如果我改变这样的代码使用 foo 的别名,情况会变坏:

But if I change the code like this to use an alias of foo, things go bad:

template<template<typename...> class TT, typename... Ts>
struct is_instantiation_of : public std::false_type { };

template<template<typename...> class TT, typename... Ts>
struct is_instantiation_of<TT, TT<Ts...>> : public std::true_type { };

template<typename T>
struct foo {};

//Added: alias for foo
template<typename T>
using foo_alt = foo<T>;

template<typename FooType>
struct bar {
  //Changed: want to use foo_alt instead of foo here
  static_assert(is_instantiation_of<foo_alt,FooType>::value, ""); //fail
};

int main(int,char**) {
  //both of these fail:
  bar<foo<int>> b;
  bar<foo_alt<int>> b2;

  return 0;
}

这可以解决吗?

推荐答案

不,它不能被解决(至少不显着改变设计)。问题是,如C ++ 11标准第14.5.7 / 2节所述,不能推导出模板别名:

No, it cannot be solved (not without changing the design significantly at least). The problem is that template alias names are not deduced, as mentioned in paragraph 14.5.7/2 of the C++11 Standard:


当模板标识引用别名模板的特殊化时,它等价于相关的类型
,通过将其template-arguments替换为别名的type-id中的模板参数
模板。 [注意:永远不会推断别名模板名称.- end note ]

示例:


[示例:

[ Example:

template<class T> struct Alloc { / ... / };
template<class T> using Vec = vector<T, Alloc<T>>;
Vec<int> v; // same as vector<int, Alloc<int>> v;

...

template<template<class> class TT>
void f(TT<int>);
f(v); // error: Vec not deduced                          <=== Relevant

...

- 结束示例]

在具体情况下,部分专门化,编译器不会推断你的类型是一个实例化 foo_alt (因为 foo_alt 的别名模板),并且选择主模板。

In your concrete case, the problem is that when trying to match the partial specialization, the compiler won't deduce that your type is an instantiation of foo_alt (since foo_alt is the name of an alias template), and the primary template gets picked.

如果要使用别名模板,则必须放弃一些通用性,特定于 foo 的特性:

If you want to use alias templates, you will have to give up a bit of genericity and create a type trait specific for foo:

#include <type_traits>

template<typename T>
struct foo {};

template<typename T>
struct is_instantiation_of_foo : std::false_type { };

template<typename...Ts>
struct is_instantiation_of_foo<foo<Ts...>> : std::true_type { };

那么你可以这样使用:

template<typename FooType>
struct bar {
  static_assert(is_instantiation_of_foo<FooType>::value, ""); //fail
};

现在,以下程序中的断言都不会触发:

Now, none of the assertions in the following program will fire:

template<typename T>
using foo_alt = foo<T>;

int main(int,char**) {
  // None of these fail:
  bar<foo<int>> b;
  bar<foo_alt<int>> b2;

  return 0;
}

这里是live example

这篇关于在模板中使用模板别名,而不是模板的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆