C++  N4606 (70)7.1.7.2 Simple type specifiers [dcl.type.simple] p167

#はじめに
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.

#(70)7.1.7.2 Simple type specifiers [dcl.type.simple]
p167

```c++:p167.cpp
// N4606 Committee Draft, Standard for Programming Language C++
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/n4606.pdf 
#define msg "p167.cpp(70)7.1.7.2 Simple type specifiers [dcl.type.simple]"

#include <iostream>

const int&& foo();
int i;
struct A { double x; };
const A* a = new A();
decltype(foo()) x1 = 17; // type is const int&&
decltype(i) x2; // type is int
decltype(a->x) x3; // type is double
decltype((a->x)) x4 = x3; // type is const double&
template struct A { ~A() = delete; };
template auto h()
-> A;
template auto i(T) // identity
-> T;
template auto f(T) // #1
-> decltype(i(h())); // forces completion of A and implicitly uses
// A::~A() for the temporary introduced by the
// use of h(). (A temporary is not introduced
// as a result of the use of i().)
template auto f(T) // #2
-> void;
auto g() -> void {
  f(42); // OK: calls #2. (#1 is not a viable candidate: type
  // deduction fails (14.8.2) because A::~A()
  // is implicitly used in its decltype-specifier)
}
template auto q(T)
-> decltype((h())); // does not force completion of A; A::~A() is
// not implicitly used within the context of this decltype-specifier
void r() {
  q(42); // Error: deduction against q succeeds, so overload resolution
  // selects the specialization “q(T) -> decltype((h())) [with T=int]”.
  // The return type is A, so a temporary is introduced and its
  // destructor is used, so the program is ill-formed.
}
int main(){
  int i=1;
  foo(i);
  std::cout<< msg << std::endl;
  return EXIT_SUCCESS;
}
```

```shell_session
$ ./cppgl17.sh p167
$ clang++ p167.cpp
p167.cpp:15:19: error: class cannot be defined in an explicit instantiation; if this declaration is meant to be a class definition, remove
      the 'template' keyword
template struct A { ~A() = delete; };
~~~~~~~~~         ^
p167.cpp:15:17: error: redefinition of 'A'
template struct A { ~A() = delete; };
                ^
p167.cpp:9:8: note: previous definition is here
struct A { double x; };
       ^
p167.cpp:16:15: error: explicit instantiation of 'h' does not refer to a function template, variable template, member function, member
      class, or static data member
template auto h()
              ^
p167.cpp:18:17: error: unknown type name 'T'
template auto i(T) // identity
                ^
p167.cpp:19:4: error: unknown type name 'T'
-> T;
   ^
p167.cpp:18:15: error: explicit instantiation of 'i' does not refer to a function template, variable template, member function, member
      class, or static data member
template auto i(T) // identity
              ^
p167.cpp:20:17: error: unknown type name 'T'
template auto f(T) // #1
                ^
p167.cpp:21:15: error: use of undeclared identifier 'h'
-> decltype(i(h())); // forces completion of A and implicitly uses
              ^
p167.cpp:20:15: error: explicit instantiation of 'f' does not refer to a function template, variable template, member function, member
      class, or static data member
template auto f(T) // #1
              ^
p167.cpp:25:17: error: unknown type name 'T'
template auto f(T) // #2
                ^
p167.cpp:25:15: error: explicit instantiation of 'f' does not refer to a function template, variable template, member function, member
      class, or static data member
template auto f(T) // #2
              ^
p167.cpp:28:3: error: use of undeclared identifier 'f'
  f(42); // OK: calls #2. (#1 is not a viable candidate: type
  ^
p167.cpp:32:17: error: unknown type name 'T'
template auto q(T)
                ^
p167.cpp:33:14: error: use of undeclared identifier 'h'
-> decltype((h())); // does not force completion of A; A::~A() is
             ^
p167.cpp:32:15: error: explicit instantiation of 'q' does not refer to a function template, variable template, member function, member
      class, or static data member
template auto q(T)
              ^
p167.cpp:36:3: error: use of undeclared identifier 'q'
  q(42); // Error: deduction against q succeeds, so overload resolution
  ^
p167.cpp:43:3: error: no matching function for call to 'foo'
  foo(i);
  ^~~
p167.cpp:7:13: note: candidate function not viable: requires 0 arguments, but 1 was provided
const int&& foo();
            ^
17 errors generated.

$ g++-7 p167.cpp
p167.cpp:15:17: error: redefinition of 'struct A'
 template struct A { ~A() = delete; };
                 ^
p167.cpp:9:8: note: previous definition of 'struct A'
 struct A { double x; };
        ^
p167.cpp:17:4: error: 'h' is not a template function
 -> A;
    ^
p167.cpp:18:18: error: 'i' is not a template function
 template auto i(T) // identity
                  ^
p167.cpp:18:16: error: expected ';' before '(' token
 template auto i(T) // identity
                ^
p167.cpp:20:18: error: 'f' is not a template function
 template auto f(T) // #1
                  ^
p167.cpp:20:16: error: expected ';' before '(' token
 template auto f(T) // #1
                ^
p167.cpp:25:18: error: 'f' is not a template function
 template auto f(T) // #2
                  ^
p167.cpp:25:16: error: expected ';' before '(' token
 template auto f(T) // #2
                ^
p167.cpp: In function 'void g()':
p167.cpp:28:3: error: 'f' was not declared in this scope
   f(42); // OK: calls #2. (#1 is not a viable candidate: type
   ^
p167.cpp: At global scope:
p167.cpp:32:18: error: 'q' is not a template function
 template auto q(T)
                  ^
p167.cpp:32:16: error: expected ';' before '(' token
 template auto q(T)
                ^
p167.cpp: In function 'void r()':
p167.cpp:36:3: error: 'q' was not declared in this scope
   q(42); // Error: deduction against q succeeds, so overload resolution
   ^
p167.cpp: In function 'int main()':
p167.cpp:43:8: error: too many arguments to function 'const int&& foo()'
   foo(i);
        ^
p167.cpp:7:13: note: declared here
 const int&& foo();
             ^~~
```

#検討事項
コンパイルエラーをなくす修正方法。
clang++とg++のコンパイルエラーの違いの背景。


#参考資料

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