C++N4606 (197)14.7.1 Implicit instantiation [temp.inst]p394

#はじめに
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)
Target: x86_64-apple-darwin17.4.0

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

#(197)14.7.1 Implicit instantiation [temp.inst]p394

```c++:p394.cpp
// N4606 Committee Draft, Standard for Programming Language C++
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/n4606.pdf
#define msg "(197)14.7.1 Implicit instantiation [temp.inst]p394.cpp"
// Edited by Dr. Ogawa Kiyoshi. Compile procedure and results record.

#include <iostream>

template<class T> class B { /* ... */
};
template<class T> class D : public B<T> { /* ... */
};
void f(void*);
void f(B<int>*);
void g(D<int>* p, D<char>* pp, D<double>* ppp) {
  f(p); // instantiation of D<int> required: call f(B<int>*)
  B<char>* q = pp; // instantiation of D<char> required:
// convert D<char>* to B<char>*
  delete ppp; // instantiation of D<double> required
}

template<class T> class X;
X<char> ch; // error: incomplete type X<char>

template<class T, class U>
struct Outer {
  template<class X, class Y> struct Inner;
  template<class Y> struct Inner<T, Y>; // #1a
  template<class Y> struct Inner<T, Y> { }; // #1b; OK: valid redeclaration of #1a
  template<class Y> struct Inner<U, Y> { }; // #2
};
Outer<int, int> outer; // error at #2

template<class T> struct Z {
  void f();
  void g();
};
void h() {
  Z<int> a; // instantiation of class Z<int> required
  Z<char>* p; // instantiation of class Z<char> not required
  Z<double>* q; // instantiation of class Z<double> not required
  a.f(); // instantiation of Z<int>::f() required
  p->g(); // instantiation of class Z<char> required, and
// instantiation of Z<char>::g() required
}

template <class T> struct S {
  operator int();
};
void f(int);
void f(S<int>&);
void f(S<float>);
void g(S<int>& sr) {
  f(sr); // instantiation of S<int> allowed but not required
// instantiation of S<float> allowed but not required
};

namespace N {
template<class T> class List {
public:
  T* get();
};
}
template<class K, class V> class Map {
public:
  N::List<V> lt;
  V get(K);
};
void g(Map<const char*,int>& m) {
  int i = m.get("Nicholas");
}

template<class T> void f(T x, T y = ydef(T()), T z = zdef(T()));
class A { };
A zdef(A);
void g(A a, A b, A c) {
  f(a, b, c); // no default argument instantiation
  f(a, b); // default argument z = zdef(T()) instantiated
  f(a); // ill-formed; ydef is not declared
}

template<class T> class X {
  X<T>* p; // OK
  X<T*> a; // implicit generation of X<T> requires
// the implicit instantiation of X<T*> which requires
// the implicit instantiation of X<T**> which ...
};

int main() {
  std::cout<< msg << std::endl;
  return EXIT_SUCCESS;
}
```

```shell_session
$ ./cppgl17.sh p394
$ clang++ p394.cpp
p394.cpp:20:9: error: implicit instantiation of undefined template 'X<char>'
X<char> ch; // error: incomplete type X<char>
        ^
p394.cpp:19:25: note: template is declared here
template<class T> class X;
                        ^
p394.cpp:27:26: error: class template partial specialization 'Inner<int, Y>' cannot be redeclared
template<class Y> struct Inner<U, Y> { }; // #2
                         ^
p394.cpp:29:17: note: in instantiation of template class 'Outer<int, int>' requested here
Outer<int, int> outer; // error at #2
                ^
p394.cpp:25:26: note: previous declaration of class template partial specialization 'Inner<int, type-parameter-0-0>' is here
template<class Y> struct Inner<T, Y>; // #1a
                         ^
p394.cpp:70:37: error: use of undeclared identifier 'ydef'
template<class T> void f(T x, T y = ydef(T()), T z = zdef(T()));
                                    ^
p394.cpp:76:1: note: in instantiation of default function argument expression for 'f<A>' required here
f(a); // ill-formed; ydef is not declared
^
3 errors generated.

$ g++-7 p394.cpp
p394.cpp:20:9: error: aggregate 'X<char> ch' has incomplete type and cannot be defined
 X<char> ch; // error: incomplete type X<char>
         ^~
p394.cpp: In function 'void f(T, T, T) [with T = A]':
p394.cpp:70:41: error: 'ydef' was not declared in this scope
 template<class T> void f(T x, T y = ydef(T()), T z = zdef(T()));
                                     ~~~~^~~~~
p394.cpp:70:41: note: suggested alternative: 'zdef'
 template<class T> void f(T x, T y = ydef(T()), T z = zdef(T()));
                                     ~~~~^~~~~
                                     zdef
p394.cpp:76:4: note:   when instantiating default argument for call to void f(T, T, T) [with T = A]
 f(a); // ill-formed; ydef is not declared
    ^


```

タブを２つの空白に変換しているスクリプトは下記。

```sh:a.sh
#!/bin/bash
astyle -s2 -c < $1.cpp > $1s2.cpp
cat $1s2.cpp
```

#検討事項
コンパイルエラーをなくす修正方法
役に立つまたは意味のある出力


#参考資料


N4606 Working Draft 2016, ISO/IEC 14882, C++ standardのコード断片をコンパイルするためにしていること
https://qiita.com/kaizen_nagoya/items/a8d7ee2f2e29e76c19c1


コンパイル用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

「C++完全理解ガイド」の同意できること上位10
https://qiita.com/kaizen_nagoya/items/aa5744e0c4a8618c7671

#文書履歴
0.10 初稿 2080420