继承构造函数是否与C ++ 0x中的模板一起使用? [英] Does inheriting constructors work with templates in C++0x?

查看:120
本文介绍了继承构造函数是否与C ++ 0x中的模板一起使用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在C ++ 0x中,您可以使用使用关键字继承构造函数,如下所示:

In C++0x, you can use the using keyword to inherit constructors, like so:

class B { B(int) {} };

class A : public B { using B::B; };

这将隐式声明一个 A(int)构造函数。这是否与模板一起使用?

Which will implicitly declare an A(int) constructor. Does this work with templates?

class B { B(int) {} };

template<class T> class A : public T { using T::T; };

T :: T 编译器找出左边 T ,因为对模板参数使用scope操作符是正常的,但是确定右边 T 是构造函数是一种特殊情况。事实上,它似乎有一个歧义:如果我有一个方法 T B ,我试图在 A 中添加重载(这是编译器如何解释这样的使用声明pre-C ++ 0x)?

Within T::T, I expect the compiler to figure out the left hand T since using the scope operator on template arguments is normal, but figuring out that the right hand T is the constructor is a special case. In fact it appears there's an ambiguity: what if I have a method called T in B that I'm trying to add overloads to in A (that's how a compiler would interpret such a using declaration pre-C++0x)?

推荐答案

是的,它的原因是名称查找机制。继承 - 构造函数声明的机制很简单:如果使用声明的名称引用基类构造函数,那么它是一个继承构造函数声明。在3.4.3.1 [class.qual] p2中,我们找到:

Yes it works, and the reason is the name lookup mechanism. The mechanism a inheriting-constructors declaration works is simple: If the using declaration's name refers to base class constructors, that's an inheriting constructors declaration. At 3.4.3.1[class.qual]p2 we find:


在构造函数是可接受的查找结果并且嵌套-name-specifier指定类C

In a lookup in which the constructor is an acceptable lookup result and the nested-name-specifier nominates a class C


  • 如果在C语言中查找嵌套名称指定之后指定的名称是在成员声明的使用声明(7.3.3)中,如果在嵌套名称之后指定的名称,则注入类名C(条款9)或

  • -specifier与嵌套名称说明符最后一个组件中的标识符或simple-template-id的模板名相同

该名称被认为是命名类C的构造函数。

the name is instead considered to name the constructor of class C.

这是从构造函数定义工作,这也是使继承构造函数声明工作的段落。第二个项目符号适用于这种情况:

This is the paragraph that makes out of class constructor definitions work, and this is also the paragraph that makes inheriting constructor declarations work. The second bullet applies in this case:

struct B {
  B(int) { }
};

typedef B mytype;

struct A : B {
  // "name ... is the same as the identifier ... in the last component ..."
  using mytype::mytype;
};


template<typename T> using same = T;

struct C : B {
  // "name ... is the same as the template-name ... in the last component ..."
  same<B>::same;
};

后面的示例在以下情况下也很有用

The latter example proves also useful in cases such as the following

template<template<typename> class Base>
struct X : Base<int> {
  using Base<int>::Base;
};

总结:


  • 上面的第一个项目是一个语义规则 - 如果嵌套名称说明符之后的名称引用注入的类名( B :: B code> mytype :: B ),那么它将被转换为引用构造函数。

  • The first bullet above is a semantic rule - if the name after the nested name specifier refers to the injected class name (B::B or mytype::B), then it will be translated to refer to the constructor(s).

第二个项目符号是一个句法规则 - 名称必须匹配 - 其含义无关紧要 - 可能有一个成员 c>中提供的模板参数中的 基本,如下所示,但是using声明仍然会导入构造函数,不是命名成员 Base

The second bullet is a syntactic rule - the names just must match - their meaning is irrelevant otherwise - there could have been a member called Base in the template argument provided to X, such as in the following, but the using declaration would still import the constructors and do not name the member Base:

template<typename T> struct D { private: T Base; };
X<D> x; // valid, the private member is *not* touched!


这篇关于继承构造函数是否与C ++ 0x中的模板一起使用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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