标签: template-aliases

为什么别名模板会给出冲突的声明?

从Clang到g ++的一些C++ 11代码的端口

template<class T>
using value_t = typename T::value_type;

template<class>
struct S
{
    using value_type = int;
    static value_type const C = 0;
};

template<class T> 
value_t<S<T>> // gcc error, typename S<T>::value_type does work
const S<T>::C;

int main() 
{    
    static_assert(S<int>::C == 0, "");
}
Run Code Online (Sandbox Code Playgroud)

给出了Clang(版本3.1到SVN主干)与任何g ++版本的不同行为.对于后者我得到的错误,这样的

prog.cc:13:13: error: conflicting declaration 'value_t<S<T> > S< <template-parameter-1-1> >::C'
 const S<T>::C;
             ^
prog.cc:8:29: note: previous declaration as 'const value_type S< <template-parameter-1-1> >::C'
     static value_type const C = 0;
                             ^
prog.cc:13:13: error: declaration …
Run Code Online (Sandbox Code Playgroud)

c++ templates g++ c++11 template-aliases

41
推荐指数
1
解决办法
1767
查看次数

别名模板的包扩展

似乎只能在别名模板的pack参数的位置扩展pack参数.对于类或函数模板,情况并非如此:

template <class T, class... Args> struct x { using type = T; };

template <class T, class... Args> using x_t     = typename x<T, Args...>::type;
template <class... Args>          using x_fix_t = typename x<Args...>::type;

template <class... Args> auto f(Args...) -> void {
  typename x<Args...>::type v1; // OK
  x_t<Args...> v2; // Error
  x_fix_t<Args...> v3; // OK
}
Run Code Online (Sandbox Code Playgroud)

更简单的情况:

template <class T, class U> using y_t = T;

template <class... Args> auto f(Args...) -> void {
  y_t<Args...> v4; // Error
} …
Run Code Online (Sandbox Code Playgroud)

c++ language-lawyer variadic-templates c++11 template-aliases

40
推荐指数
1
解决办法
1812
查看次数

我可以使用模板别名作为模板模板参数吗?

我可以使用模板别名作为模板模板参数吗?

template <template <typename...> class> struct foo {};

template <typename T> using simple_ptr = std::unique_ptr<T>;

foo<std::unique_ptr> a; // this doesn't work, std::unique_ptr has two parameters
foo<simple_ptr> b; // does this work?
Run Code Online (Sandbox Code Playgroud)

c++ templates c++11 template-aliases

37
推荐指数
1
解决办法
1981
查看次数

可变参数模板别名作为模板参数

首先是一些代码,然后是一些上下文,然后是问题:

template <typename T> using id = T;

template <template <typename...> class F, typename... T>
using apply1 = F <T...>;

template <template <typename...> class F>
struct apply2
{
    template <typename... T>
    using map = F <T...>;
};

// ...

cout << apply1 <id, int>() << endl;
cout << apply2 <id>::map <int>() << endl;
Run Code Online (Sandbox Code Playgroud)

clang 3.3和gcc 4.8.1都编译了这个没有错误,应用了标识元函数int,因此两个表达式都计算为默认值int(零).

id有一段template <typename>时间的事实apply1,apply2期待template <typename...>我首先关注我.然而,这是很方便的,这个例子的作品,因为否则像元函数apply1,apply2必须是这么多参与.

另一方面,这样的模板别名在现实世界的代码中引起严重的问题,我无法在这里重现:gcc频繁的内部编译器错误,以及clang的频繁出现意外行为(仅在更高级的SFINAE测试中).

经过几个月的试验和错误,我现在安装并尝试(实验)gcc 4.9.0上的代码,这里出现错误:

test.cpp: …
Run Code Online (Sandbox Code Playgroud)

c++ template-meta-programming variadic-templates c++11 template-aliases

17
推荐指数
1
解决办法
2598
查看次数

模板typedef的新"使用"语法解决了什么问题?

在C++ 11中,您可以通过执行类似的操作来创建"类型别名"

template <typename T>
using stringpair = std::pair<std::string, T>;
Run Code Online (Sandbox Code Playgroud)

但这与您期望的模板typedef看起来有所不同:

template <typename T>
typedef std::pair<std::string, T> stringpair;
Run Code Online (Sandbox Code Playgroud)

所以这提出了一个问题 - 为什么他们需要提出一个新的语法?什么是旧的typedef语法不起作用?

我意识到最后一点没有编译,但为什么不能编译?

c++ templates typedef c++11 template-aliases

16
推荐指数
2
解决办法
542
查看次数

部分模板专业化的g ++ Bug

我正在为g ++(版本4.8.1_1,Macports)和clang ++(版本3.3,Macports)编写一些TMP密码.虽然g ++拒绝使用UNBRIDLED FURY的以下代码清单,但是 clang ++会用优雅辉煌来编译它.

  • 哪个编译器在右边?(我强烈怀疑它是g ++,但我希望在提交错误报告之前得到其他人的一些保证.)
  • 您有任何简单或优雅的变通方法可供建议吗?(我需要使用模板别名,因此切换到结构,导致g ++接受代码,不是一个选项.)

这是代码清单,专为您而制作.

template <class... Ts>
struct sequence;

template <int T>
struct integer;

// This definition of `extents` causes g++ to issue a compile-time error.
template <int... Ts>
using extents = sequence<integer<Ts>...>;

// However, this definition works without any problems.
// template <int... Ts>
// struct extents;

template <int A, int B, class Current>
struct foo;

template <int A, int B, int... …
Run Code Online (Sandbox Code Playgroud)

c++ templates template-specialization c++11 template-aliases

14
推荐指数
1
解决办法
520
查看次数

变量模板别名作为模板参数(第2部分)

这是另一个问题的后续行动.它指的是同样的问题(我希望),但使用一个完全不同的例子来说明它.原因是在前面的示例中,只有实验性GCC 4.9因编译器错误而失败.在此示例中,Clang和GCC 4.8.1也以不同方式失败:Clang产生意外结果,GCC 4.8.1报告不同的错误消息.

上一个问题的答案或多或少地说代码是有效的,问题在于GCC的实验版本.但这个结果让我更加怀疑.几个月来我一直困扰着我怀疑有相关(或相同)的问题,这是我第一次有一个小的具体例子来说明.

所以,这里有一些代码.首先,一些通用代码将SFINAE应用于由可变参数模板别名元函数指定的任意测试F:

#include <iostream>
using namespace std;

using _true  = integral_constant <bool, true>;
using _false = integral_constant <bool, false>;

template <typename T> using pass = _true;

template <template <typename...> class F>
struct test
{
    template <typename... A> static _false           _(...);
    template <typename... A> static pass <F <A...> > _(int);
};

template <template <typename...> class F, typename... A>
using sfinae = decltype(test <F>::template _<A...>(0));
Run Code Online (Sandbox Code Playgroud)

第二,一个特定的测试,检查给定的类是否定义了一个名为的类型type:

template <typename T> using type_of  = …
Run Code Online (Sandbox Code Playgroud)

c++ templates template-meta-programming variadic-templates template-aliases

13
推荐指数
1
解决办法
859
查看次数

在模板别名中解压缩参数包

我将variadic模板解压缩到模板别名时遇到了问题.

以下代码适用于Clang 3.4和GCC 4.8,但在GCC 4.9中失败:

template <typename T, typename...>
using front_type = T;

template <typename... Ts>
struct foo
{
  using front = front_type<Ts...>;
};
Run Code Online (Sandbox Code Playgroud)

GCC 4.9抱怨:

test.cc:7:37: error: pack expansion argument for non-pack parameter 'T' of alias template 'template<class T, class ...> using front_type = T'
       using front = front_type<Ts...>;
                                     ^
test.cc:1:15: note: declared here
     template <typename T, typename...>
               ^
Run Code Online (Sandbox Code Playgroud)

存在一个提交的GCC错误(#59498),但这应该失败吗?以下是C++核心语言#1430的一些上下文,"将扩展打包到固定别名模板参数列表":

最初,包扩展无法扩展到固定长度的模板参数列表,但在N2555中已更改.这适用于大多数模板,但会导致别名模板出现问题.

在大多数情况下,别名模板是透明的; 当它在模板中使用时,我们可以在依赖模板参数中替换.但是,如果template-id对非可变参数使用包扩展,则这不起作用.例如:

  template<class T, class U, class V>
  struct S {};

  template<class …
Run Code Online (Sandbox Code Playgroud)

c++ variadic-templates c++11 template-aliases gcc4.9

13
推荐指数
1
解决办法
969
查看次数

模板别名如何影响模板参数推导?

在C++ 03中,模板参数推导在某些上下文中不会发生.例如:

template <typename T> struct B {};

template <typename T>
struct A
{
    typedef B<T> type;
};

template <typename T>
void f(typename A<T>::type);

int main()
{
    B<int> b;
    f(b);  // ERROR: no match
}
Run Code Online (Sandbox Code Playgroud)

这里int不推断T,因为嵌套类型A<T>::type是非推断的上下文.

我是否写过这样的函数:

template <typename T> struct B {};

template <typename T>
void f(B<T>);

int main()
{
    B<int> b;
    f(b);
}
Run Code Online (Sandbox Code Playgroud)

一切都很好,因为B<T> 推断的背景.

但是,在C++ 11中,模板别名可用于以类似于第二个示例的语法伪装嵌套类型.例如:

template <typename T> struct B {};

template <typename T>
struct A
{
    typedef …
Run Code Online (Sandbox Code Playgroud)

c++ templates c++11 template-aliases

12
推荐指数
1
解决办法
1185
查看次数

嵌套类中的模板别名可见性

考虑以下:

template<typename X>
struct Z {};

struct A
{
    using Z = ::Z<int>;

    struct B : Z
    {
        using C = Z;
    };
};
Run Code Online (Sandbox Code Playgroud)

编译好了.尼斯.但现在添加另一个参数Z:

template<typename X, typename Y>
struct Z {};

struct A
{
    template<typename X>
    using Z = ::Z<X, int>;

    struct B : Z<B>
    {
        using C = Z<B>;  // error: too few template arguments for class template 'Z'
    };
};
Run Code Online (Sandbox Code Playgroud)

好吧,也许有意义的是,在派生嵌套类时Z,类中模板别名的定义A是可见的B,但在其体内却不可见,因为全局定义Z有两个参数,所以触发错误.

但是为什么第一种情况下的行为不同,何时Z只是一个类型别名A …

c++ nested-class language-lawyer c++11 template-aliases

12
推荐指数
1
解决办法
380
查看次数