C++N4606 (80)7.3.3 The using declaration [namespace.udecl] 182

#はじめに
N4606 Working Draft, Standard for Programming Language C++
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/#mailing2016-11
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/n4606.pdf

n4606は、ISO/IEC JTC1 SC22 WG21の作業原案(Working Draft)です。
公式のISO/IEC 14882原本ではありません。
ISO/IEC JTC1 SC22 WG21では、可能な限り作業文書を公開し、幅広い意見を求めています。
一連の記事はコード断片をコンパイルできる形にする方法を検討してコンパイル、リンク、実行して、規格案の原文と処理系(g++, Clang++)との違いを確認し、技術内容を検討し、ISO/IEC JTC1 SC22 WG21にフィードバックするために用います。
また、CERT C++, MISRA C++等のコーディング標準のコード断片をコンパイルする際の参考にさせていただこうと考えています。CERT C++, MISRA C++が標準化の動きとの時間的なずれがあれば確認できれば幸いです。また、boostライブラリとの関連、Linux OS, TOPPERSカーネル、g++(GCC), clang++(LLVM）との関係も調査中です。
何か、抜け漏れ、耳より情報がありましたらおしらせくださると幸いです。

##作業方針
１）コンパイルエラーを収集する。
２）コンパイルエラーをなくす方法を検討する。
コンパイルエラーになる例を示すだけが目的のコードは、コンパイルエラーをなくすのではなく、コンパイルエラーの種類を収集するだけにする。
文法を示すのが目的のコード場合に、コンパイルエラーをなくすのに手間がかかる場合は、順次作業します。
３）リンクエラーをなくす方法を検討する。
文法を示すのが目的のコード場合に、リンクエラーをなくすのに手間がかかる場合は、順次作業します。
４）意味のある出力を作る。
コンパイル、リンクが通っても、意味のある出力を示そうとすると、コンパイル・リンクエラーが出て収拾できそうにない場合がある。順次作業します。

１）だけのものから４）まで進んだものと色々ある状態です。一歩でも前に進むご助言をお待ちしています。「検討事項」の欄に現状を記録するようにしています。

## list
N4606 Working Draft 2016, ISO/IEC 14882, C++ standard(1) coding list
https://qiita.com/kaizen_nagoya/items/df5d62c35bd6ed1c3d43/


## Compiler
###clang++ --version
clang version 6.0.0 (tags/RELEASE_600/final)

###g++-7 --version
g++-7 (Homebrew GCC 7.3.0_1) 7.3.0
Copyright (C) 2017 Free Software Foundation, Inc.

(80)7.3.3 The using declaration [namespace.udecl]
182

```c++:p172.cpp
// N4606 Committee Draft, Standard for Programming Language C++
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/n4606.pdf 
#define msg "p172.cpp(73)7.1.7.4.1 Placeholder type deduction [dcl.type.auto.deduct]"

#include <iostream>

struct B {
  void f(char);
  void g(char);
  enum E { e };
  union { int x; };
};
struct D : B {
  using B::f;
  void f(int) { f('c'); } // calls B::f(char)
  void g(int) { g('c'); } // recursively calls D::g(int)
};
class C {
  int g();
};
class D2 : public B {
  using B::f; // OK: B is a base of D2
  using B::e; // OK: e is an enumerator of base B
  using B::x; // OK: x is a union member of base B
  using C::g; // error: C isn’t a base of D2
};
struct A {
  template void f(T);
  template struct X { };
};
struct B : A {
  using A::f; // ill-formed
  using A::X; // ill-formed
};
struct X {
  int i;
  static int s;
};
void f() {
  using X::i; // error: X::i is a class member
  // and this is not a member declaration.
  using X::s; // error: X::s is a class member
  // and this is not a member declaration.
}
void f();
namespace A {
  void g();
}
namespace X {
  using ::f; // global f
  using A::g; // A’s g
}
void h()
{
  X::f(); // calls ::f
  X::g(); // calls A::g
}
namespace A {
  int i;
}
namespace A1 {
  using A::i;
  using A::i; // OK: double declaration
}
struct B {
  int i;
};
struct X : B {
  using B::i;
  using B::i; // error: double member declaration
};
namespace A {
  void f(int);
}
using A::f; // f is a synonym for A::f;
// that is, for A::f(int).
namespace A {
  void f(char);
}
void foo() {
  f('a'); // calls f(int),
} // even though f(char) exists.
void bar() {
  using A::f; // f is a synonym for A::f;
  // that is, for A::f(int) and A::f(char).
  f('a'); // calls f(char)
}
namespace A {
  int x;
}
namespace B {
  int i;
  struct g { };
  struct x { };
  void f(int);
  void f(double);
  void g(char); // OK: hides struct g
}
void func() {
  int i;
  using B::i; // error: i declared twice
  void f(char);
  using B::f; // OK: each f is a function
  f(3.5); // calls B::f(double)
  using B::g;
  g('a'); // calls B::g(char)
  struct g g1; // g1 has class type B::g
  using B::x;
  using A::x; // OK: hides struct B::x
  x = 99; // assigns to A::x
  struct x x1; // x1 has class type B::x
}
namespace B {
  void f(int);
  void f(double);
}
namespace C {
  void f(int);
  void f(double);
  void f(char);
}
void h() {
  using B::f; // B::f(int) and B::f(double)
  using C::f; // C::f(int), C::f(double), and C::f(char)
  f('h'); // calls C::f(char)
  f(1); // error: ambiguous: B::f(int) or C::f(int)?
  void f(int); // error: f(int) conflicts with C::f(int) and B::f(int)
}
struct B {
  virtual void f(int);
  virtual void f(char);
  void g(int);
  void h(int);
};
struct D : B {
  using B::f;
  void f(int); // OK: D::f(int) overrides B::f(int);
  using B::g;
  void g(char); // OK
  using B::h;
  void h(int); // OK: D::h(int) hides B::h(int)
};
void k(D* p)
{
  p->f(1); // calls D::f(int)
  p->f(’a’); // calls B::f(char)
  p->g(1); // calls B::g(int)
  p->g(’a’); // calls D::g(char)
}
struct B1 {
  B1(int);
};
struct B2 {
  B2(int);
};
struct D1 : B1, B2 {
  using B1::B1;
  using B2::B2;
};
D1 d1(0); // ill-formed: ambiguous
struct D2 : B1, B2 {
  using B1::B1;
  using B2::B2;
  D2(int); // OK: D2::D2(int) hides B1::B1(int) and B2::B2(int)
};
D2 d2(0); // calls D2::D2(int)
struct A { int x(); };
struct B : A { };
struct C : A {
  using A::x;
  int x(int);
};
struct D : B, C {
  using C::x;
  int x(double);
};
int f(D* d) {
  return d->x(); // ambiguous: B::x or C::x
}
class A {
  private:
    void f(char);
  public:
    void f(int);
  protected:
    void g();
};
class B : public A {
  using A::f; // error: A::f(char) is inaccessible
public:
  using A::g; // B::g is a public synonym for A::g
};
int main(){
  std::cout<< msg << std::endl;
  return EXIT_SUCCESS;
}
```

```shell_session
$ ./cppgl17.sh p182
$ clang++ p182.cpp
p182.cpp:25:9: error: using declaration refers into 'C::', which is not a base class of 'D2'
  using C::g; // error: C isn’t a base of D2
        ^~~
p182.cpp:28:12: error: expected '<' after 'template'
  template void f(T);
           ^
p182.cpp:29:12: error: expected '<' after 'template'
  template struct X { };
           ^
p182.cpp:31:8: error: redefinition of 'B'
struct B : A {
       ^
p182.cpp:7:8: note: previous definition is here
struct B {
       ^
p182.cpp:40:12: error: using declaration cannot refer to class member
  using X::i; // error: X::i is a class member
        ~~~^
p182.cpp:42:12: error: using declaration cannot refer to class member
  using X::s; // error: X::s is a class member
        ~~~^
p182.cpp:42:3: note: use a reference instead
  using X::s; // error: X::s is a class member
  ^~~~~
  auto &s = 
p182.cpp:46:11: error: redefinition of 'A' as different kind of symbol
namespace A {
          ^
p182.cpp:27:8: note: previous definition is here
struct A {
       ^
p182.cpp:49:11: error: redefinition of 'X' as different kind of symbol
namespace X {
          ^
p182.cpp:35:8: note: previous definition is here
struct X {
       ^
p182.cpp:51:12: error: using declaration cannot refer to class member
  using A::g; // A’s g
        ~~~^
p182.cpp:55:3: error: no member named 'f' in 'X'; did you mean simply 'f'?
  X::f(); // calls ::f
  ^~~~
  f
p182.cpp:45:6: note: 'f' declared here
void f();
     ^
p182.cpp:56:6: error: no member named 'g' in 'X'
  X::g(); // calls A::g
  ~~~^
p182.cpp:58:11: error: redefinition of 'A' as different kind of symbol
namespace A {
          ^
p182.cpp:27:8: note: previous definition is here
struct A {
       ^
p182.cpp:62:12: error: using declaration cannot refer to class member
  using A::i;
        ~~~^
p182.cpp:63:12: error: using declaration cannot refer to class member
  using A::i; // OK: double declaration
        ~~~^
p182.cpp:65:8: error: redefinition of 'B'
struct B {
       ^
p182.cpp:7:8: note: previous definition is here
struct B {
       ^
p182.cpp:68:8: error: redefinition of 'X'
struct X : B {
       ^
p182.cpp:35:8: note: previous definition is here
struct X {
       ^
p182.cpp:72:11: error: redefinition of 'A' as different kind of symbol
namespace A {
          ^
p182.cpp:27:8: note: previous definition is here
struct A {
       ^
p182.cpp:75:10: error: using declaration cannot refer to class member
using A::f; // f is a synonym for A::f;
      ~~~^
p182.cpp:77:11: error: redefinition of 'A' as different kind of symbol
namespace A {
          ^
p182.cpp:27:8: note: previous definition is here
struct A {
       ^
fatal error: too many errors emitted, stopping now [-ferror-limit=]
20 errors generated.

$ g++-7 p182.cpp
p182.cpp:146:8: error: stray '\342' in program
   p->f(???a’); // calls B::f(char)
        ^
p182.cpp:146:9: error: stray '\200' in program
   p->f(???a’); // calls B::f(char)
         ^
p182.cpp:146:10: error: stray '\231' in program
   p->f(??a’); // calls B::f(char)
          ^
p182.cpp:146:12: error: stray '\342' in program
   p->f(’a???); // calls B::f(char)
            ^
p182.cpp:146:13: error: stray '\200' in program
   p->f(’a???); // calls B::f(char)
             ^
p182.cpp:146:14: error: stray '\231' in program
   p->f(’a??); // calls B::f(char)
              ^
p182.cpp:148:8: error: stray '\342' in program
   p->g(???a’); // calls D::g(char)
        ^
p182.cpp:148:9: error: stray '\200' in program
   p->g(???a’); // calls D::g(char)
         ^
p182.cpp:148:10: error: stray '\231' in program
   p->g(??a’); // calls D::g(char)
          ^
p182.cpp:148:12: error: stray '\342' in program
   p->g(’a???); // calls D::g(char)
            ^
p182.cpp:148:13: error: stray '\200' in program
   p->g(’a???); // calls D::g(char)
             ^
p182.cpp:148:14: error: stray '\231' in program
   p->g(’a??); // calls D::g(char)
              ^
p182.cpp:25:12: error: type 'C' is not a base type for type 'D2'
   using C::g; // error: C isn’t a base of D2
            ^
p182.cpp:28:12: error: expected '<' before 'void'
   template void f(T);
            ^~~~
p182.cpp:28:19: error: 'T' has not been declared
   template void f(T);
                   ^
p182.cpp:29:12: error: expected '<' before 'struct'
   template struct X { };
            ^~~~~~
p182.cpp:31:8: error: redefinition of 'struct B'
 struct B : A {
        ^
p182.cpp:7:8: note: previous definition of 'struct B'
 struct B {
        ^
p182.cpp: In function 'void f()':
p182.cpp:40:12: error: 'X' is not a namespace or unscoped enum
   using X::i; // error: X::i is a class member
            ^
p182.cpp:42:12: error: 'X' is not a namespace or unscoped enum
   using X::s; // error: X::s is a class member
            ^
p182.cpp: At global scope:
p182.cpp:46:11: error: 'namespace A { }' redeclared as different kind of symbol
 namespace A {
           ^
p182.cpp:27:8: note: previous declaration 'struct A'
 struct A {
        ^
p182.cpp:49:11: error: 'namespace X { }' redeclared as different kind of symbol
 namespace X {
           ^
p182.cpp:35:8: note: previous declaration 'struct X'
 struct X {
        ^
p182.cpp:51:12: error: 'A::g' has not been declared
   using A::g; // A’s g
            ^
p182.cpp: In function 'void h()':
p182.cpp:55:6: error: 'f' is not a member of 'X'
   X::f(); // calls ::f
      ^
p182.cpp:56:6: error: 'g' is not a member of 'X'
   X::g(); // calls A::g
      ^
p182.cpp: At global scope:
p182.cpp:58:11: error: 'namespace A { }' redeclared as different kind of symbol
 namespace A {
           ^
p182.cpp:27:8: note: previous declaration 'struct A'
 struct A {
        ^
p182.cpp:62:12: error: 'A::i' has not been declared
   using A::i;
            ^
p182.cpp:63:12: error: 'A::i' has not been declared
   using A::i; // OK: double declaration
            ^
p182.cpp:65:8: error: redefinition of 'struct B'
 struct B {
        ^
p182.cpp:7:8: note: previous definition of 'struct B'
 struct B {
        ^
p182.cpp:68:8: error: redefinition of 'struct X'
 struct X : B {
        ^
p182.cpp:35:8: note: previous definition of 'struct X'
 struct X {
        ^
p182.cpp:72:11: error: 'namespace A { }' redeclared as different kind of symbol
 namespace A {
           ^
p182.cpp:27:8: note: previous declaration 'struct A'
 struct A {
        ^
p182.cpp:75:10: error: 'A' is not a namespace or unscoped enum
 using A::f; // f is a synonym for A::f;
          ^
p182.cpp:77:11: error: 'namespace A { }' redeclared as different kind of symbol
 namespace A {
           ^
p182.cpp:27:8: note: previous declaration 'struct A'
 struct A {
        ^
p182.cpp: In function 'void bar()':
p182.cpp:84:12: error: 'A' is not a namespace or unscoped enum
   using A::f; // f is a synonym for A::f;
            ^
p182.cpp: At global scope:
p182.cpp:88:11: error: 'namespace A { }' redeclared as different kind of symbol
 namespace A {
           ^
p182.cpp:27:8: note: previous declaration 'struct A'
 struct A {
        ^
p182.cpp:91:11: error: 'namespace B { }' redeclared as different kind of symbol
 namespace B {
           ^
p182.cpp:7:8: note: previous declaration 'struct B'
 struct B {
        ^
p182.cpp:92:7: error: redefinition of 'int i'
   int i;
       ^
p182.cpp:59:7: note: 'int i' previously declared here
   int i;
       ^
p182.cpp: In function 'void func()':
p182.cpp:101:12: error: 'B::i' has not been declared
   using B::i; // error: i declared twice
            ^
p182.cpp:103:12: error: 'B' is not a namespace or unscoped enum
   using B::f; // OK: each f is a function
            ^
p182.cpp:105:12: error: 'B' is not a namespace or unscoped enum
   using B::g;
            ^
p182.cpp:108:12: error: 'B' is not a namespace or unscoped enum
   using B::x;
            ^
p182.cpp:109:12: error: 'A::x' has not been declared
   using A::x; // OK: hides struct B::x
            ^
p182.cpp: At global scope:
p182.cpp:113:11: error: 'namespace B { }' redeclared as different kind of symbol
 namespace B {
           ^
p182.cpp:7:8: note: previous declaration 'struct B'
 struct B {
        ^
p182.cpp:117:11: error: 'namespace C { }' redeclared as different kind of symbol
 namespace C {
           ^
p182.cpp:18:7: note: previous declaration 'class C'
 class C {
       ^
p182.cpp: In function 'void h()':
p182.cpp:122:6: error: redefinition of 'void h()'
 void h() {
      ^
p182.cpp:53:6: note: 'void h()' previously defined here
 void h()
      ^
p182.cpp:123:12: error: 'B' is not a namespace or unscoped enum
   using B::f; // B::f(int) and B::f(double)
            ^
p182.cpp:124:12: error: 'C::f' has not been declared
   using C::f; // C::f(int), C::f(double), and C::f(char)
            ^
p182.cpp: At global scope:
p182.cpp:129:8: error: redefinition of 'struct B'
 struct B {
        ^
p182.cpp:7:8: note: previous definition of 'struct B'
 struct B {
        ^
p182.cpp:135:8: error: redefinition of 'struct D'
 struct D : B {
        ^
p182.cpp:13:8: note: previous definition of 'struct D'
 struct D : B {
        ^
p182.cpp: In function 'void k(D*)':
p182.cpp:146:11: error: 'a' was not declared in this scope
   p->f(’a’); // calls B::f(char)
           ^
p182.cpp: At global scope:
p182.cpp:160:8: error: call of overloaded 'D1(int)' is ambiguous
 D1 d1(0); // ill-formed: ambiguous
        ^
p182.cpp:154:3: note: candidate: B2::B2(int)
   B2(int);
   ^~
p182.cpp:158:13: note:   inherited here
   using B2::B2;
             ^~
p182.cpp:151:3: note: candidate: B1::B1(int)
   B1(int);
   ^~
p182.cpp:157:13: note:   inherited here
   using B1::B1;
             ^~
p182.cpp:156:8: note: candidate: constexpr D1::D1(const D1&)
 struct D1 : B1, B2 {
        ^~
p182.cpp:156:8: note: candidate: constexpr D1::D1(D1&&)
p182.cpp:161:8: error: redefinition of 'struct D2'
 struct D2 : B1, B2 {
        ^~
p182.cpp:21:7: note: previous definition of 'struct D2'
 class D2 : public B {
       ^~
p182.cpp:166:8: error: no matching function for call to 'D2::D2(int)'
 D2 d2(0); // calls D2::D2(int)
        ^
p182.cpp:21:7: note: candidate: D2::D2()
 class D2 : public B {
       ^~
p182.cpp:21:7: note:   candidate expects 0 arguments, 1 provided
p182.cpp:21:7: note: candidate: constexpr D2::D2(const D2&)
p182.cpp:21:7: note:   no known conversion for argument 1 from 'int' to 'const D2&'
p182.cpp:21:7: note: candidate: constexpr D2::D2(D2&&)
p182.cpp:21:7: note:   no known conversion for argument 1 from 'int' to 'D2&&'
p182.cpp:167:8: error: redefinition of 'struct A'
 struct A { int x(); };
        ^
p182.cpp:27:8: note: previous definition of 'struct A'
 struct A {
        ^
p182.cpp:168:8: error: redefinition of 'struct B'
 struct B : A { };
        ^
p182.cpp:7:8: note: previous definition of 'struct B'
 struct B {
        ^
p182.cpp:169:8: error: redefinition of 'struct C'
 struct C : A {
        ^
p182.cpp:18:7: note: previous definition of 'struct C'
 class C {
       ^
p182.cpp:173:8: error: redefinition of 'struct D'
 struct D : B, C {
        ^
p182.cpp:13:8: note: previous definition of 'struct D'
 struct D : B {
        ^
p182.cpp: In function 'int f(D*)':
p182.cpp:178:15: error: expression cannot be used as a function
   return d->x(); // ambiguous: B::x or C::x
               ^
p182.cpp: At global scope:
p182.cpp:180:7: error: redefinition of 'class A'
 class A {
       ^
p182.cpp:27:8: note: previous definition of 'class A'
 struct A {
        ^
p182.cpp:188:7: error: redefinition of 'class B'
 class B : public A {
       ^
p182.cpp:7:8: note: previous definition of 'class B'
 struct B {
        ^
```

#検討事項
コンパイルエラーをなくす修正。

#参考資料

コンパイル用shell script C版(clangとgcc)とC++版(clang++とg++)
https://qiita.com/kaizen_nagoya/items/74220c0577a512c2d7da

Clang/Clang++(LLVM) gcc/g++(GNU) コンパイラ警告等比較
https://qiita.com/kaizen_nagoya/items/9a82b958cc3aeef0403f

Qiitaに投稿するCのStyle例(暫定)
https://qiita.com/kaizen_nagoya/items/946df1528a6a1ef2bc0d

MISRA C++ 5-0-16
https://qiita.com/kaizen_nagoya/items/7df2d4e05db724752a74

C++ Templates Part1 BASICS Chapter 3. Class Templates 3.2 Use of Class Template Stack stack1test.cpp
https://qiita.com/kaizen_nagoya/items/cd5fc49106fad5a4e9ed


ISO/IEC TS 17961:2013 C Secure Coding Rules(1) All list(to be confirmed)
https://qiita.com/kaizen_nagoya/items/54e056195c4f11b850a1

C言語（C++)に対する誤解、曲解、無理解、爽快。
https://qiita.com/kaizen_nagoya/items/3f3992c9722c1cee2e3a

C Puzzle Bookの有り難み5つ、C言語規格及びCコンパイラの特性を認識
https://qiita.com/kaizen_nagoya/items/d89a48c1536a02ecdec9

'wchar.h' file not found で困った clang++ macOS
https://qiita.com/kaizen_nagoya/items/de15cd46d657517fac11

Open POSIX Test Suiteの使い方を調べはじめました
https://qiita.com/kaizen_nagoya/items/644d5e407f5faf96e6dc

MISRA-C 2012 Referenceに掲載している文献の入手可能性を確認
https://qiita.com/kaizen_nagoya/items/96dc8b125e462d5575bb

どうやって MISRA Example Suiteをコンパイルするか
https://qiita.com/kaizen_nagoya/items/fbdbff5ff696e2ca7f00

MISRA C まとめ #include <misra_c.h>
https://qiita.com/kaizen_nagoya/items/f1a79a7cbd281607c7c9

#文書履歴
0.10 初稿 2080417