标签: using-declaration

C++ 0x与使用声明混淆

这种情况会发生什么:

struct A {
  void f();
};

struct B : virtual A {
  using A::f;
};

struct C : virtual A {
  using A::f;
};

struct D : B, C { 
  void g() {
    f();
  }
};
Run Code Online (Sandbox Code Playgroud)

感兴趣的是 f().显然,f根据10.2FDIS 的查找成功并找到A::f.但是,哪些候选人会考虑重载决议?规范说13.3.1p4:

对于由using声明引入到派生类中的非转换函数,该函数被认为是派生类的成员,用于定义隐式对象参数的类型.

这样做的目的是使单个类,如果这样一类同时包含自己的成员函数和using声明带来的基类函数的名称为范围,即重载解析过程中的所有功能,考生在他们的隐含对象是相同类型参数.但这对于上面的例子意味着什么呢?候选人是否会如下?

void F1(B&)
void F2(C&)
// call arguments: (lvalue D)
Run Code Online (Sandbox Code Playgroud)

这似乎是错误的,因为根据我们在查找结果集中只有一个声明10.2p7.我们该如何解读?

c++ using-declaration overload-resolution c++11

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

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
查看次数

在C++中使用指令与使用声明交换

请参考以下代码:

#include <algorithm>

namespace N
{

    template <typename T>
    class C
    {
    public:
        void SwapWith(C & c)
        {
            using namespace std; // (1)
            //using std::swap;   // (2)
            swap(a, c.a);
        }
    private:
        int a;
    };

    template <typename T>
    void swap(C<T> & c1, C<T> & c2)
    {
        c1.SwapWith(c2);
    }

}

namespace std
{

    template<typename T> void swap(N::C<T> & c1, N::C<T> & c2)
    {
        c1.SwapWith(c2);
    }

}
Run Code Online (Sandbox Code Playgroud)

如上所述,代码无法在Visual Studio 2008/2010上编译.错误是:

'void N::swap(N::C<T> &,N::C<T> &)' : could not deduce template argument for 'N::C<T> &' …
Run Code Online (Sandbox Code Playgroud)

c++ swap using-directives using-declaration

14
推荐指数
2
解决办法
8370
查看次数

C++在继承构造函数中使用带有typename的声明

在阅读这个问题时,我发现了一个奇怪的观点:

template <typename T>
class Subclass : public Baseclass<T>
{
public:
    using typename Baseclass<T>::Baseclass;
    //    ^^^^^^^^
};
Run Code Online (Sandbox Code Playgroud)

既然typename,Baseclass<T>::Baseclass应该注入类名,而不是构造函数.据我所知,情况与此相同:

template <typename T>
class Base
{
public:
    typedef short some_type;
};

template <typename T>
class Sub : public Base<T>
{
public:
    using typename Base<T>::some_type;
};
Run Code Online (Sandbox Code Playgroud)

为了确保,我写了一个测试代码.

#include <iostream>

template <typename T>
class Base
{
public:
    Base() { std::cout << "A::A()\n"; }
    Base(int) { std::cout << "A::A(int)\n"; }
    Base(const char *) { std::cout << "A::A(const …
Run Code Online (Sandbox Code Playgroud)

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

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

定义成员函数时编译错误,但仅在GCC中编译

以下程序与MSVS,clang和GCC编译时没有错误:

class A;

namespace Y {
    using ::A;
    class A {};
}

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

现在让我们定义一个成员函数.现在它仍然可以编译MSVS和clang,但不能与GCC编译:

class A;

namespace Y {
    using ::A;
    class A { void f() {} };
}

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

GCC给出以下错误消息:

  • prog.cc:5:22:错误:'void A :: f()'的定义不在包含'A'[-fpermissive]的命名空间中

这是为什么?这是GCC中的错误吗?

如果该程序的第二个版本违反了c ++标准的规则,它违反了什么规则,为什么MSVS和clang没有为该违规提供诊断消息?

这是c ++标准含糊不清的情况吗?

从错误消息看起来GCC错误地认为我们违反了以下规则:

我们没有违反此规则,因为成员函数定义在类定义中.我的理论是,海湾合作委员会混淆了宣言类A; 在全局命名空间中,在命名空间Y中有类定义类A {...}.我认为我们在GCC中有一个错误.

通过海湾合作委员会,他们宣布同一实体.通过观察在程序的第一个版本中可以看出,在使用GCC进行编译时,可以使用:: A作为main中的完整类型.MSVS也是如此.然而,对于Clang,他们宣布了不同的实体.这种差异可能是因为c ++标准的模糊性.无论这种模棱两可,我们显然都没有违反http://eel.is/c++draft/class.mfct#2.这个规则很清楚.

相关问题:与GCC中使用声明编译相同范围内的类声明,但不是MSVS

c++ gcc using-declaration language-lawyer

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

命名空间使用声明(GCC/VS2010中的错误)?

namespace A{
   int i;
}

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

VS2010 - 编译好

gcc(ideone) - 编译好

Comeau - 给出错误""ComeauTest.c",第10行:错误:"i"已经在当前范围内使用A :: i声明;"

$ 7.3.3/8 - "使用声明是一种声明,因此可以在允许多个声明的情况下(并且仅在何处)重复使用."

这里的例子表明代码确实是不正确的.

那么,这是GCC和VS2010中的一个错误吗?

编辑2:

删除using directives与手头查询无关的倍数.

c++ namespaces using-declaration

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

在C++ 11中使用声明是允许/需要"typename"吗?

以下代码在g ++和clang中正确编译:

template<typename T>
struct foo
{
    class iterator;
    using bar = foo::iterator;
};

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

但MSVC 2013会出现以下错误:

foo.cpp(9): error C2061: syntax error : identifier 'iterator'
          foo.cpp(10) : see reference to class template instantiation 'foo<T>' being compiled
foo.cpp(9): error C2238: unexpected token(s) preceding ';'
Run Code Online (Sandbox Code Playgroud)

如果我将该行更改为:

using bar = typename foo::iterator;
Run Code Online (Sandbox Code Playgroud)

然后所有三个编译器都成功编译.原始版本是否正确?(即这是一个MSVC错误,还是一个gcc/clang扩展)

c++ typename using-declaration c++11

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

是`使用Base :: operator T`允许`T`是模板类型参数?

考虑这个例子:

struct B { operator int(); };

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

GCC接受代码,而Clang和MSVC拒绝它.哪个是对的?

请注意,如果基类型是相关的,则所有编译器都接受以下代码:

template<class T>
struct B { operator T(); };

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

c++ templates using-declaration conversion-operator

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

using-declaration不能正常工作

在下面的例子中,我试图通过在课堂上将其隐藏起来来隐藏using Employee::showEveryDept最后一个子DesignerElayer-

#include <iostream>

class Employee {
private:
    char name[5] = "abcd";
    void allDept() { std::cout << "Woo"; }

public:
    void tellName() { std::cout << name << "\n"; }
    virtual void showEveryDept()
    {
        std::cout << "Employee can see every dept\n";
        allDept();
    }
};

class ELayer : public Employee {
private:
    using Employee::showEveryDept;

protected:
    ELayer() {}

public:
    using Employee::tellName;
};

class Designer : public ELayer {
private:
    char color = 'r';

public:
    void showOwnDept() { …
Run Code Online (Sandbox Code Playgroud)

c++ polymorphism inheritance using-declaration c++11

12
推荐指数
3
解决办法
915
查看次数

从依赖基类访问类型

有谁知道为什么使用声明似乎不适用于从依赖基类导入类型名称?它们适用于成员变量和函数,但至少在GCC 4.3中,它们似乎被忽略了类型.

template <class T>
struct Base
{
  typedef T value_type;
};

template <class T>
struct Derived : Base<T>
{
  // Version 1: error on conforming compilers
  value_type get();

  // Version 2: OK, but unwieldy for repeated references
  typename Base<T>::value_type get();

  // Version 3: OK, but unwieldy for many types or deep inheritance
  typedef typename Base<T>::value_type value_type;
  value_type get();

  // Version 4: why doesn't this work?
  using typename Base<T>::value_type;
  value_type get(); // GCC: `value_type' is not a type
};
Run Code Online (Sandbox Code Playgroud)

我有一个基类,有一组allocator样式的typedef,我想在几个继承级别继承.到目前为止,我发现的最佳解决方案是上面的版本3,但我很好奇为什么版本4似乎不起作用.GCC接受使用声明,但似乎忽略它. …

c++ templates dependent-name using-declaration

11
推荐指数
1
解决办法
3445
查看次数