标签: using-declaration

在C++ 11中'typedef'和'using'有什么区别?

我知道在C++ 11中我们现在可以using用来写类型别名,比如typedefs:

typedef int MyInt;
Run Code Online (Sandbox Code Playgroud)

从我的理解,相当于:

using MyInt = int;
Run Code Online (Sandbox Code Playgroud)

这种新语法来自于努力表达" template typedef":

template< class T > using MyType = AnotherType< T, MyAllocatorType >;
Run Code Online (Sandbox Code Playgroud)

但是,对于前两个非模板示例,标准中是否还有其他细微差别?例如,typedefs以"弱"方式进行别名.也就是说,它不会创建新类型,而只会创建新名称(这些名称之间隐含的转换).

它是否与using生成新类型相同或是否生成新类型?有什么不同吗?

c++ typedef using-declaration c++11

833
推荐指数
8
解决办法
25万
查看次数

为什么两个 using 子句解析为同一类型在 gcc 中被视为模棱两可

我有两个带有 using 子句的基类

 class MultiCmdQueueCallback {
  using NetworkPacket  = Networking::NetworkPacket;
  ....
 }


 class PlcMsgFactoryImplCallback {
   using NetworkPacket = Networking::NetworkPacket;
  ....
 }
Run Code Online (Sandbox Code Playgroud)

然后我声明一个类

class PlcNetwork : 
  public RouterCallback, 
  public PlcMsgFactoryImplCallback, 
  public MultiCmdQueueCallback {
  private:
    void sendNetworkPacket(const NetworkPacket &pdu);
}
Run Code Online (Sandbox Code Playgroud)

编译器然后标记对“NetworkPacket”的错误引用是不明确的“sendNetworkPacket(NetworkPacket &...”

现在,两个“使用子句”都解析为相同的底层类 Networking:NetworkPacket

事实上,如果我将方法声明替换为:

 void sendNetworkPacket(const Networking::NetworkPacket &pdu);
Run Code Online (Sandbox Code Playgroud)

它编译得很好。

为什么编译器将每个 using 子句视为不同的类型,即使它们都指向相同的底层类型。这是标准规定的还是我们有编译器错误?

c++ using-declaration

31
推荐指数
3
解决办法
1704
查看次数

使用声明的奇怪行为

请参阅以下代码

struct A { using type = int; };
struct B : private A {};
struct C : B { using base_type = A; };
Run Code Online (Sandbox Code Playgroud)

所有的gcc 6.1,clang 3.8和msvc 2015更新3都拒绝编译它,因为A它不是一个可访问的名称,C因为它A是一个私有基础B.似乎gcc认为Ausing base_type = A指默认构造函数A.msvc和clang似乎没有.

也许编译错误是由于继承触发的名称注入(因为修改using base_type = Ausing base_type = ::A使所有编译器工作正常),但我想知道这个奇怪的错误是否是标准所说的.

更具体地说,

  1. 据我所知,不是A::type,A只是一个类名(虽然gcc误解为一个函数名),它不是引入C 内部 A也不引入B.为什么这个名字被认为是私人的B
  2. 该编译错误是否应被视为错误,或者是标准规范的边缘情况?

c++ using-declaration private-inheritance name-lookup c++11

26
推荐指数
1
解决办法
1200
查看次数

派生类中的using-declaration不会隐藏从基类派生的相同函数

看看下面的代码:

struct A {
public:
    virtual void f(){std::cout << "in A";};
};

struct B : A{
public:
   virtual void f(){std::cout << "in B";};
   int a;
};

struct C : B{
    using A::f;
    void test(){f();}
};


int main() 
{
    C c;
    c.f(); // calls B::f, the final overrider
    c.C::f(); // calls A::f because of the using-declaration
    c.test(); //calls B::f
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

根据我的理解,B::f()in C应该隐藏使用声明A::f()带来的内容C; 如果是的话,为什么c.C::f()还要打电话A::f()

如果c.C::f()调用A::f(),这应该意味着,在范围 …

c++ using-declaration

25
推荐指数
1
解决办法
544
查看次数

使用声明链接的程序在MSVS和clang上编译但在GCC上编译

根据c ++标准,以下程序是否格式良好或格式不正确?

namespace X { int i; }

namespace Y { using X::i; }

int main() { using X::i; using Y::i; }
Run Code Online (Sandbox Code Playgroud)

我用不同的编译器得到了不同的结果:

我不想修复这个程序让它在GCC上编译.我只是想知道c ++标准对此有何看法以及为什么三个编译器的行为不同.此外,我想如果这是任何这些编译器中的错误的结果.

c++ declaration using-declaration language-lawyer

19
推荐指数
2
解决办法
376
查看次数

使用声明不能在功能范围内重复.这是为什么?

在[namespace.udecl]/10中,您有以下示例:

namespace A {
    int i;
}
namespace A1 {
    using A::i;
    using A::i; // OK: double declaration
}
void f() {
    using A::i;
    using A::i; // error: double declaration
}
Run Code Online (Sandbox Code Playgroud)

这个片段编译成clang.

c++ using-declaration language-lawyer c++14

18
推荐指数
1
解决办法
247
查看次数

在using-declaration中,依赖名称可以在模板替换后呈现给构造函数吗?

在这个例子中:

template<class T>
struct S : T
{
    using T::X;
};
Run Code Online (Sandbox Code Playgroud)

T::X是指部件上的从属名称XT.如果S<T>实例化为T = X:

struct X
{
    X(int) {}
};
...
S<X> s(42);
Run Code Online (Sandbox Code Playgroud)

using声明是否会成为继承构造函数?

Clang拒绝代码DEMO,而g ++接受它.

请注意,如果我们写:

using T::X::X;
Run Code Online (Sandbox Code Playgroud)

两个编译器都接受代码并将其视为继承构造函数.被using T::X允许通过标准成为继承,构造函数?

c++ templates using-declaration language-lawyer inheriting-constructors

18
推荐指数
1
解决办法
174
查看次数

C++使用关键字

这两种using关键字用法有什么区别:

using boost::shared_ptr;
Run Code Online (Sandbox Code Playgroud)

using namespace boost;
Run Code Online (Sandbox Code Playgroud)

c++ namespaces using-declaration

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

尝试通过using-declaration定义命名空间成员

考虑以下程序.根据c ++标准(参考所需标准的相关部分)是否格式良好:

namespace X { extern int i; }

namespace N { using X::i; }

int N::i = 1;

int main() {}
Run Code Online (Sandbox Code Playgroud)

我为不同的编译器得到了不同的结果.我正在试图弄清楚我应该为哪个编译器提交错误报告:

  • Clang:给出以下编译器错误:名称空间'N'中没有名为'i'的成员

  • GCC和Visual C++编译它没有错误.

为了比较,下面给出了所有三个编译器的编译器错误:

namespace X { void f(); }

namespace N { using X::f; }

void N::f() {};

int main() {}
Run Code Online (Sandbox Code Playgroud)

c++ namespaces definition using-declaration language-lawyer

16
推荐指数
1
解决办法
230
查看次数

C++ - 如何从可变数量的基数引入重载集.

如果派生类定义了相同的名称,派生类将隐藏基类的重载名称,但我们总是可以使用using-declaration引入该重载集:

template <class BASE>
class A : public BASE
{
public:
  using BASE::some_method;
  void some_method();
}
Run Code Online (Sandbox Code Playgroud)

但是如果我从可变参数基类引入所有重载集呢?我可以写这样的东西吗?

template <class... BASES>
class A : public BASES...
{
public:
  using BASES::some_method...;
  void some_method();
}
Run Code Online (Sandbox Code Playgroud)

我考虑过使用一个帮助类:

template <class... BASES>
struct helper;

template <>
struct helper<> {};

template <class OnlyBase>
struct helper<OnlyBase> : OnlyBase
{
  using OnlyBase::some_method;
};

template <class Base1, class... OtherBases>
struct helper<Base1, OtherBases> : public Base1, public helper<OtherBases...>
{
  using Base1::some_method;
  using helper<OtherBases...>::some_method;
};
Run Code Online (Sandbox Code Playgroud)

它确实有效.但它需要大量的输入(当然我可以使用宏,但我尽可能尝试使用c ++的编译时功能),当我想引入更多方法时,我必须在那段代码中做出很多改变.

一个完美的答案是一个简单的语法,但如果没有,我将使用帮助类.

c++ inheritance overloading using-declaration variadic-templates

15
推荐指数
1
解决办法
344
查看次数