13.10.3.2 Deducing template arguments from a function call [temp.deduct.call] C++N4910:2022 (240) p426.cpp

# はじめに(Introduction)

N4910  Working Draft, Standard for Programming Language C++

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/n4910.pdf

n4910は、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）との関係も調査中です。
何か、抜け漏れ、耳より情報がありましたらおしらせくださると幸いです。

 <この項は書きかけです。順次追記します。>

## 背景(back ground)
C/C++でコンパイルエラーが出ると、途方にくれることがしばしばあります。
何回かに１回は、該当するエラーが検索できます。
ただ、条件が違っていて、そこでの修正方法では目的を達成しないこともしばしばです。いろいろな条件のコンパイルエラーとその対応方法について、広く記録することによって、いつか同じエラーに遭遇した時にやくに立つことを目指しています。

この半年の間で、三度、自分のネットでの記録に助けられたことがあります。
また過去に解決できなかった記録を１０種類以上、最近になって解決できたことがあります。それは、主に次の３つの情報に基づいています。

https://stackoverflow.com
https://cpprefjp.github.io
http://ja.cppreference.com/

また
https://researchmap.jp/joub9b3my-1797580/#_1797580
に記載したサイトのお世話になっています。

## 作業方針(sequence)
Clang++では-std=c++03, C++2bの2種類
g++では-std=c++03, c++2bの２種類
でコンパイルし、

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

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

### C++N4910:2022 Standard Working Draft on ISO/IEC 14882(0) sample code compile list  

https://qiita.com/kaizen_nagoya/items/fc957ddddd402004bb91

### C++N4741, 2018 Standard Working Draft on ISO/IEC 14882 sample code compile list
https://qiita.com/kaizen_nagoya/items/3294c014044550896010

### C++N4606, 2016符号断片編纂一覧(example code compile list)
C++N4606, 2016 Working Draft 2016, ISO/IEC 14882, C++ standard(1) Example code compile list
https://qiita.com/kaizen_nagoya/items/df5d62c35bd6ed1c3d43/

### C++N3242, 2011 sample code compile list on clang++ and g++
https://qiita.com/kaizen_nagoya/items/685b5c1a2c17c1bf1318

## 編纂器(Compiler)
### clang++ --version
> Debian clang version 14.0.5-++20220610033153+c12386ae247c-1~exp1~20220610153237.151
Target: x86_64-pc-linux-gnu, Thread model: posix, InstalledDir: /usr/bin

### g++- --version
> g++ (GCC) 12.1.0  Copyright (C) 2022 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

# 13.10.3.2 Deducing template arguments from a function call [temp.deduct.call] C++N4910:2022 (240) p426.cpp

## 算譜(source code)

```c++:p426.cpp
// C++N4910 Committee Draft, Standard for Programming Language C++
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/n4910.pdf
const char * n4910 = "13.10.3.2 Deducing template arguments from a function call [temp.deduct.call] C++N4910:2022 (240) p426.cpp";
// Debian clang version 14.0.5-++20220610033153+c12386ae247c-
// g++ (GCC) 12.1.0 Copyright (C) 2022 Free Software Foundation, Inc.
// Edited by Dr. Ogawa Kiyoshi. Compile procedure and results record.
// C++N4910:2022 Standard Working Draft on ISO/IEC 14882(0) sample code compile list
// https://qiita.com/kaizen_nagoya/items/fc957ddddd402004bb91

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cassert>
#include <coroutine>
#include <vector>
#include <complex>
#include <map>
#include <atomic>
#include <unordered_map>
#include <typeinfo>

using namespace std;

// Example 1
template<class T> void f(std::initializer_list<T>);
f({1,2,3});
f({1,"asdf"});
template<class T> void g(T);
g({1,2,3});
// T deduced as int
// error: T deduced as both int and const char*
// error: no argument deduced for T template<class T, int N> void h(T const(&)[N]);
h({1,2,3}); // T deduced as int; N deduced as 3 template<class T> void j(T const(&)[3]);
j({42}); // T deduced as int; array bound not considered
struct Aggr {
    int i;
    int j;
};
template<int N> void k(Aggr const(&)[N]);
k({1,2,3}); // error: deduction fails, no conversion from int to Aggr k({{1},{2},{3}}); // OK, N deduced as 3
template<int M, int N> void m(int const(&)[M][N]);
m({{1,2},{3,4}}); // M and N both deduced as 2
template<class T, int N> void n(T const(&)[N], T);
n({{1},{2},{3}},Aggr()); // OK, T is Aggr, N is 3
template<typename T, int N> void o(T (* const (&)[N])(T)) { }
int f1(int);
int f41(int);
char f41(char);
o({ &f1, &f41 });
o({ &f1, static_cast<char(*)(char)>(&f41) });
// OK, T deduced as int from first element, nothing
// deduced from second element, N deduced as 2
// error: conflicting deductions for T
// [Example 2:
template<class ... Types> void f(Types& ...);
template<class T1, class ... Types> void g(T1, Types ...);
template<class T1, class ... Types> void g1(Types ..., T1);
void h(int x, float& y) {
    const int z = x;
    f(x, y, z);
    g(x, y, z);
    g1(x, y, z);
    g1<int, int, int>(x, y, z);
}
// Types deduced as int, float, const int
// T1 deduced as int; Types deduced as float, int // error: Types is not deduced
// OK, no deduction occurs
// [Example 3:
template<class T> int f3(const T&);
int n1 = f3(5); // calls f<int>(const int&)
const int i = 0;
int n2 = f3(i); // calls f<int>(const int&)
template <class T> int g3(volatile T&);
int n3 = g3(i); // calls g<const int>(const volatile int&)
// [Example 4:
template <class T> int f4(T&& heisenreference);
template <class T> int g4(const T&&);
int i4;
int n1 = f4(i4);
int n2 = f4(0);
int n3 = g4(i4);
template <class T> struct A {
    template <class U>
    A(T&&, U&&, int*);
    A(T&&, int*);
};
// cal ls f<int&>(int&)
// cal ls f<int>(int&&)
// error: would call g<int>(const int&&), which
// would bind an rvalue reference to an lvalue
// #1: T&& is not a forwarding reference.
// U&& is a forwarding reference.
// #2
template <class T> A(T&&, int*) -> A<T>;
// #3: T&& is a forwarding reference.
int *ip;
A a{i, 0, ip};
A a0{0, 0, ip};
A a2{i, ip};
// error: cannot deduce from #1
// uses #1 to deduce A<int> and #1 to initialize
// uses #3 to deduce A<int&> and #2 to initialize
// [Example 5:
template <typename... T> struct X;
template <> struct X<> {};
template <typename T, typename... Ts>
struct X<T, Ts...> : X<Ts...> {};
struct D : X<int> {};
struct E : X<>, X<int> {};
template <typename... T>
int f5(const X<T...>&);
int x5 = f5(D()); // calls f<int>, not f<>
// B is X<>, C is X<int> int z = f(E()); // calls f<int>, not f<>
// [Example 6 :
// Only one function of an overload set matches the call so the function parameter is a deduced context.
template <class T> int f6(T (*p)(T));
int g6(int);
int g6(char);
int i6 = f6(g6); // calls f(int (*)(int))
// [Example 7 :
// Ambiguous deduction causes the second function parameter to be a non-deduced context.
template <class T> int f7(T, T (*p)(T));
int g7(int);
char g7(char);
int i7 = f7(1, g7);
//  [Example 8 :
// calls f(int, int (*)(int))
// The overload set contains a template, causing the second function parameter to be a non-deduced context.
template <class T> int f8(T, T (*p)(T));
char g8(char);
template <class T> T g8(T);
int i8 = f8(1, g8); // calls f(int, int (*)(int))
int main() {
    cout  <<  n4910 << endl;
    return EXIT_SUCCESS;
}
```

## Script

```bash:clgc.sh
#!/bin/sh
rm $1l
rm $1g
echo "$ clang++ $1.cpp -std=03 -o $1l -I. -Wall" 
clang++ $1.cpp -std=c++03 -o $1l -I. -Wall
if [  -e $1l ]; then
./$1l 
fi
rm $1l
echo "$ clang++ $1.cpp -std=2b -o $1l -I. -Wall"
clang++ $1.cpp -std=c++2b -o $1l -I. -Wall
if [  -e $1l ]; then
./$1l
fi
echo "\r"
echo "$ g++ $1.cpp -std=03 -o $1g -I. -Wall"
g++ $1.cpp -std=c++03 -o $1g -I. -Wall
if [ -e $1g ]; then
./$1g
fi
rm $1g
echo "\r"
echo "$ g++ $1.cpp -std=2b -o $1g -I. -Wall"
g++ $1.cpp -std=c++2b -o $1g -I. -Wall
if [ -e $1g ]; then
./$1g 
fi
```
## 編纂・実行結果(compile and go)

```ubuntu:bash
# ./clgc.sh p426
rm: cannot remove 'p426l': No such file or directory
rm: cannot remove 'p426g': No such file or directory
$ clang++ p426.cpp -std=c++03 -o p426l -I. -Wall
In file included from p426.cpp:19:
In file included from /usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/atomic:38:
/usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/c++0x_warning.h:32:2: error: This file requires compiler and library support for the ISO C++ 2011 standard. This support must be enabled with the -std=c++11 or -std=gnu++11 compiler options.
#error This file requires compiler and library support \
 ^
p426.cpp:26:24: warning: variable templates are a C++14 extension [-Wc++14-extensions]
template<class T> void f(std::initializer_list<T>);
                       ^
p426.cpp:26:24: error: variable has incomplete type 'void'
p426.cpp:26:31: error: no member named 'initializer_list' in namespace 'std'
template<class T> void f(std::initializer_list<T>);
                         ~~~~~^
p426.cpp:26:48: error: 'T' does not refer to a value
template<class T> void f(std::initializer_list<T>);
                                               ^
p426.cpp:26:16: note: declared here
template<class T> void f(std::initializer_list<T>);
               ^
p426.cpp:26:50: error: expected expression
template<class T> void f(std::initializer_list<T>);
                                                 ^
p426.cpp:27:1: error: C++ requires a type specifier for all declarations
f({1,2,3});
^
p426.cpp:27:3: error: expected expression
f({1,2,3});
  ^
p426.cpp:28:1: error: C++ requires a type specifier for all declarations
f({1,"asdf"});
^
p426.cpp:28:3: error: expected expression
f({1,"asdf"});
  ^
p426.cpp:30:1: error: C++ requires a type specifier for all declarations
g({1,2,3});
^
p426.cpp:30:3: error: expected expression
g({1,2,3});
  ^
p426.cpp:34:1: error: C++ requires a type specifier for all declarations
h({1,2,3}); // T deduced as int; N deduced as 3 template<class T> void j(T const(&)[3]);
^
p426.cpp:34:3: error: expected expression
h({1,2,3}); // T deduced as int; N deduced as 3 template<class T> void j(T const(&)[3]);
  ^
p426.cpp:35:1: error: C++ requires a type specifier for all declarations
j({42}); // T deduced as int; array bound not considered
^
p426.cpp:35:3: error: expected expression
j({42}); // T deduced as int; array bound not considered
  ^
p426.cpp:38:1: error: C++ requires a type specifier for all declarations
k({1,2,3}); // error: deduction fails, no conversion from int to Aggr k({{1},{2},{3}}); // OK, N deduced as 3
^
p426.cpp:38:3: error: expected expression
k({1,2,3}); // error: deduction fails, no conversion from int to Aggr k({{1},{2},{3}}); // OK, N deduced as 3
  ^
p426.cpp:39:52: error: C++ requires a type specifier for all declarations
template<int M, int N> void m(int const(&)[M][N]); m({{1,2},{3,4}}); // M and N both deduced as 2
                                                   ^
p426.cpp:39:54: error: expected expression
template<int M, int N> void m(int const(&)[M][N]); m({{1,2},{3,4}}); // M and N both deduced as 2
                                                     ^
fatal error: too many errors emitted, stopping now [-ferror-limit=]
1 warning and 20 errors generated.
rm: cannot remove 'p426l': No such file or directory
$ clang++ p426.cpp -std=c++2b -o p426l -I. -Wall
p426.cpp:27:1: error: C++ requires a type specifier for all declarations
f({1,2,3});
^
p426.cpp:28:1: error: C++ requires a type specifier for all declarations
f({1,"asdf"});
^
p426.cpp:30:1: error: C++ requires a type specifier for all declarations
g({1,2,3});
^
p426.cpp:34:1: error: C++ requires a type specifier for all declarations
h({1,2,3}); // T deduced as int; N deduced as 3 template<class T> void j(T const(&)[3]);
^
p426.cpp:35:1: error: C++ requires a type specifier for all declarations
j({42}); // T deduced as int; array bound not considered
^
p426.cpp:38:1: error: C++ requires a type specifier for all declarations
k({1,2,3}); // error: deduction fails, no conversion from int to Aggr k({{1},{2},{3}}); // OK, N deduced as 3
^
p426.cpp:39:52: error: C++ requires a type specifier for all declarations
template<int M, int N> void m(int const(&)[M][N]); m({{1,2},{3,4}}); // M and N both deduced as 2
                                                   ^
p426.cpp:40:52: error: C++ requires a type specifier for all declarations
template<class T, int N> void n(T const(&)[N], T); n({{1},{2},{3}},Aggr()); // OK, T is Aggr, N is 3
                                                   ^
p426.cpp:45:3: error: C++ requires a type specifier for all declarations
  o({ &f1, &f41 });
  ^
p426.cpp:46:3: error: C++ requires a type specifier for all declarations
  o({ &f1, static_cast<char(*)(char)>(&f41) });
  ^
p426.cpp:54:11: error: redefinition of 'h' as different kind of symbol
     void h(int x, float& y) {
          ^
p426.cpp:34:1: note: previous definition is here
h({1,2,3}); // T deduced as int; N deduced as 3 template<class T> void j(T const(&)[3]);
^
p426.cpp:58:8: error: no matching function for call to 'g1'
       g1(x, y, z);
       ^~
p426.cpp:53:44: note: candidate function [with T1 = int, Types = <>] not viable: requires 1 argument, but 3 were provided
  template<class T1, class ... Types> void g1(Types ..., T1);
                                           ^
p426.cpp:75:5: error: redefinition of 'n1'
int n1 = f4(i4);
    ^
p426.cpp:66:5: note: previous definition is here
int n1 = f3(5); // calls f<int>(const int&)
    ^
p426.cpp:76:5: error: redefinition of 'n2'
int n2 = f4(0);
    ^
p426.cpp:68:5: note: previous definition is here
int n2 = f3(i); // calls f<int>(const int&)
    ^
p426.cpp:77:5: error: redefinition of 'n3'
int n3 = g4(i4);
    ^
p426.cpp:70:5: note: previous definition is here
int n3 = g3(i); // calls g<const int>(const volatile int&)
    ^
p426.cpp:77:10: error: no matching function for call to 'g4'
int n3 = g4(i4);
         ^~
p426.cpp:73:24: note: candidate function [with T = int] not viable: expects an rvalue for 1st argument
template <class T> int g4(const T&&);
                       ^
p426.cpp:93:3: error: no viable constructor or deduction guide for deduction of template arguments of 'A'
A a{i, 0, ip};
  ^
p426.cpp:80:5: note: candidate function [with T = const int, U = int] not viable: expects an rvalue for 1st argument
    A(T&&, U&&, int*);
    ^
p426.cpp:81:3: note: candidate function template not viable: requires 2 arguments, but 3 were provided
  A(T&&, int*);
  ^
p426.cpp:90:20: note: candidate function template not viable: requires 2 arguments, but 3 were provided
template <class T> A(T&&, int*) -> A<T>; 
                   ^
p426.cpp:78:27: note: candidate function template not viable: requires 1 argument, but 3 were provided
template <class T> struct A {
                          ^
p426.cpp:105:17: warning: direct base 'X<>' is inaccessible due to ambiguity:
    struct E -> X<>
    struct E -> X<int> -> X<> [-Winaccessible-base]
     struct E : X<>, X<int> {};
                ^~~
1 warning and 17 errors generated.

$ g++ p426.cpp -std=c++03 -o p426g -I. -Wall
In file included from /usr/local/include/c++/12.1.0/atomic:38,
                 from p426.cpp:19:
/usr/local/include/c++/12.1.0/bits/c++0x_warning.h:32:2: error: #error This file requires compiler and library support for the ISO C++ 2011 standard. This support must be enabled with the -std=c++11 or -std=gnu++11 compiler options.
   32 | #error This file requires compiler and library support \
      |  ^~~~~
p426.cpp:26:24: error: variable or field 'f' declared void
   26 | template<class T> void f(std::initializer_list<T>);
      |                        ^
p426.cpp:26:31: error: 'initializer_list' is not a member of 'std'; did you mean 'uninitialized_fill'?
   26 | template<class T> void f(std::initializer_list<T>);
      |                               ^~~~~~~~~~~~~~~~
      |                               uninitialized_fill
p426.cpp:26:49: error: expected primary-expression before '>' token
   26 | template<class T> void f(std::initializer_list<T>);
      |                                                 ^
p426.cpp:26:50: error: expected primary-expression before ')' token
   26 | template<class T> void f(std::initializer_list<T>);
      |                                                  ^
p426.cpp:27:2: error: expected constructor, destructor, or type conversion before '(' token
   27 | f({1,2,3});
      |  ^
p426.cpp:27:10: error: expected unqualified-id before ')' token
   27 | f({1,2,3});
      |          ^
p426.cpp:28:2: error: expected constructor, destructor, or type conversion before '(' token
   28 | f({1,"asdf"});
      |  ^
p426.cpp:28:13: error: expected unqualified-id before ')' token
   28 | f({1,"asdf"});
      |             ^
p426.cpp:30:2: error: expected constructor, destructor, or type conversion before '(' token
   30 | g({1,2,3});
      |  ^
p426.cpp:30:10: error: expected unqualified-id before ')' token
   30 | g({1,2,3});
      |          ^
p426.cpp:34:2: error: expected constructor, destructor, or type conversion before '(' token
   34 | h({1,2,3}); // T deduced as int; N deduced as 3 template<class T> void j(T const(&)[3]);
      |  ^
p426.cpp:34:10: error: expected unqualified-id before ')' token
   34 | h({1,2,3}); // T deduced as int; N deduced as 3 template<class T> void j(T const(&)[3]);
      |          ^
p426.cpp:35:2: error: expected constructor, destructor, or type conversion before '(' token
   35 | j({42}); // T deduced as int; array bound not considered
      |  ^
p426.cpp:35:7: error: expected unqualified-id before ')' token
   35 | j({42}); // T deduced as int; array bound not considered
      |       ^
p426.cpp:38:2: error: expected constructor, destructor, or type conversion before '(' token
   38 | k({1,2,3}); // error: deduction fails, no conversion from int to Aggr k({{1},{2},{3}}); // OK, N deduced as 3
      |  ^
p426.cpp:38:10: error: expected unqualified-id before ')' token
   38 | k({1,2,3}); // error: deduction fails, no conversion from int to Aggr k({{1},{2},{3}}); // OK, N deduced as 3
      |          ^
p426.cpp:39:53: error: expected constructor, destructor, or type conversion before '(' token
   39 | template<int M, int N> void m(int const(&)[M][N]); m({{1,2},{3,4}}); // M and N both deduced as 2
      |                                                     ^
p426.cpp:39:67: error: expected unqualified-id before ')' token
   39 | template<int M, int N> void m(int const(&)[M][N]); m({{1,2},{3,4}}); // M and N both deduced as 2
      |                                                                   ^
p426.cpp:40:53: error: expected constructor, destructor, or type conversion before '(' token
   40 | template<class T, int N> void n(T const(&)[N], T); n({{1},{2},{3}},Aggr()); // OK, T is Aggr, N is 3
      |                                                     ^
p426.cpp:40:67: error: expected unqualified-id before ',' token
   40 | template<class T, int N> void n(T const(&)[N], T); n({{1},{2},{3}},Aggr()); // OK, T is Aggr, N is 3
      |                                                                   ^
p426.cpp:40:74: error: expected constructor, destructor, or type conversion before ')' token
   40 | template<class T, int N> void n(T const(&)[N], T); n({{1},{2},{3}},Aggr()); // OK, T is Aggr, N is 3
      |                                                                          ^
p426.cpp:45:4: error: expected constructor, destructor, or type conversion before '(' token
   45 |   o({ &f1, &f41 });
      |    ^
p426.cpp:45:18: error: expected unqualified-id before ')' token
   45 |   o({ &f1, &f41 });
      |                  ^
p426.cpp:46:4: error: expected constructor, destructor, or type conversion before '(' token
   46 |   o({ &f1, static_cast<char(*)(char)>(&f41) });
      |    ^
p426.cpp:46:46: error: expected unqualified-id before ')' token
   46 |   o({ &f1, static_cast<char(*)(char)>(&f41) });
      |                                              ^
p426.cpp:51:18: warning: variadic templates only available with '-std=c++11' or '-std=gnu++11' [-Wc++11-extensions]
   51 |   template<class ... Types> void f(Types& ...);
      |                  ^~~
p426.cpp:51:43: warning: variadic templates only available with '-std=c++11' or '-std=gnu++11' [-Wc++11-extensions]
   51 |   template<class ... Types> void f(Types& ...);
      |                                           ^~~
p426.cpp:52:28: warning: variadic templates only available with '-std=c++11' or '-std=gnu++11' [-Wc++11-extensions]
   52 |   template<class T1, class ... Types> void g(T1, Types ...);
      |                            ^~~
p426.cpp:52:56: warning: variadic templates only available with '-std=c++11' or '-std=gnu++11' [-Wc++11-extensions]
   52 |   template<class T1, class ... Types> void g(T1, Types ...);
      |                                                        ^~~
p426.cpp:53:28: warning: variadic templates only available with '-std=c++11' or '-std=gnu++11' [-Wc++11-extensions]
   53 |   template<class T1, class ... Types> void g1(Types ..., T1);
      |                            ^~~
p426.cpp:53:53: warning: variadic templates only available with '-std=c++11' or '-std=gnu++11' [-Wc++11-extensions]
   53 |   template<class T1, class ... Types> void g1(Types ..., T1);
      |                                                     ^~~
p426.cpp: In function 'void h(int, float&)':
p426.cpp:58:10: error: no matching function for call to 'g1(int&, float&, const int&)'
   58 |        g1(x, y, z);
      |        ~~^~~~~~~~~
p426.cpp:53:44: note: candidate: 'template<class T1, class ... Types> void g1(Types ..., T1)'
   53 |   template<class T1, class ... Types> void g1(Types ..., T1);
      |                                            ^~
p426.cpp:53:44: note:   template argument deduction/substitution failed:
p426.cpp:58:10: note:   candidate expects 1 argument, 3 provided
   58 |        g1(x, y, z);
      |        ~~^~~~~~~~~
p426.cpp: At global scope:
p426.cpp:72:28: error: expected ',' or '...' before '&&' token
   72 | template <class T> int f4(T&& heisenreference);
      |                            ^~
p426.cpp:73:34: error: expected ',' or '...' before '&&' token
   73 | template <class T> int g4(const T&&);
      |                                  ^~
p426.cpp:75:5: error: redefinition of 'int n1'
   75 | int n1 = f4(i4);
      |     ^~
p426.cpp:66:5: note: 'int n1' previously declared here
   66 | int n1 = f3(5); // calls f<int>(const int&)
      |     ^~
p426.cpp:76:5: error: redefinition of 'int n2'
   76 | int n2 = f4(0);
      |     ^~
p426.cpp:68:5: note: 'int n2' previously declared here
   68 | int n2 = f3(i); // calls f<int>(const int&)
      |     ^~
p426.cpp:77:5: error: redefinition of 'int n3'
   77 | int n3 = g4(i4);
      |     ^~
p426.cpp:70:5: note: 'int n3' previously declared here
   70 | int n3 = g3(i); // calls g<const int>(const volatile int&)
      |     ^~
p426.cpp:80:8: error: expected ',' or '...' before '&&' token
   80 |     A(T&&, U&&, int*);
      |        ^~
p426.cpp:81:6: error: expected ',' or '...' before '&&' token
   81 |   A(T&&, int*);
      |      ^~
p426.cpp:90:23: error: expected ',' or '...' before '&&' token
   90 | template <class T> A(T&&, int*) -> A<T>;
      |                       ^~
p426.cpp:90:40: error: expected constructor, destructor, or type conversion before ';' token
   90 | template <class T> A(T&&, int*) -> A<T>;
      |                                        ^
p426.cpp:93:1: error: invalid use of template-name 'A' without an argument list
   93 | A a{i, 0, ip};
      | ^
p426.cpp:93:1: note: class template argument deduction is only available with '-std=c++17' or '-std=gnu++17'
p426.cpp:78:27: note: 'template<class T> struct A' declared here
   78 | template <class T> struct A {
      |                           ^
p426.cpp:94:1: error: invalid use of template-name 'A' without an argument list
   94 | A a0{0, 0, ip};
      | ^
p426.cpp:94:1: note: class template argument deduction is only available with '-std=c++17' or '-std=gnu++17'
p426.cpp:78:27: note: 'template<class T> struct A' declared here
   78 | template <class T> struct A {
      |                           ^
p426.cpp:95:1: error: invalid use of template-name 'A' without an argument list
   95 | A a2{i, ip};
      | ^
p426.cpp:95:1: note: class template argument deduction is only available with '-std=c++17' or '-std=gnu++17'
p426.cpp:78:27: note: 'template<class T> struct A' declared here
   78 | template <class T> struct A {
      |                           ^
p426.cpp:100:24: warning: variadic templates only available with '-std=c++11' or '-std=gnu++11' [-Wc++11-extensions]
  100 |      template <typename... T> struct X;
      |                        ^~~
p426.cpp:102:36: warning: variadic templates only available with '-std=c++11' or '-std=gnu++11' [-Wc++11-extensions]
  102 |      template <typename T, typename... Ts>
      |                                    ^~~
p426.cpp:105:13: warning: direct base 'X<>' inaccessible in 'E' due to ambiguity [-Winaccessible-base]
  105 |      struct E : X<>, X<int> {};
      |             ^
p426.cpp:106:19: warning: variadic templates only available with '-std=c++11' or '-std=gnu++11' [-Wc++11-extensions]
  106 | template <typename... T>
      |                   ^~~
rm: cannot remove 'p426g': No such file or directory

$ g++ p426.cpp -std=c++2b -o p426g -I. -Wall
p426.cpp:27:2: error: expected constructor, destructor, or type conversion before '(' token
   27 | f({1,2,3});
      |  ^
p426.cpp:27:10: error: expected unqualified-id before ')' token
   27 | f({1,2,3});
      |          ^
p426.cpp:28:2: error: expected constructor, destructor, or type conversion before '(' token
   28 | f({1,"asdf"});
      |  ^
p426.cpp:28:13: error: expected unqualified-id before ')' token
   28 | f({1,"asdf"});
      |             ^
p426.cpp:30:2: error: expected constructor, destructor, or type conversion before '(' token
   30 | g({1,2,3});
      |  ^
p426.cpp:30:10: error: expected unqualified-id before ')' token
   30 | g({1,2,3});
      |          ^
p426.cpp:34:2: error: expected constructor, destructor, or type conversion before '(' token
   34 | h({1,2,3}); // T deduced as int; N deduced as 3 template<class T> void j(T const(&)[3]);
      |  ^
p426.cpp:34:10: error: expected unqualified-id before ')' token
   34 | h({1,2,3}); // T deduced as int; N deduced as 3 template<class T> void j(T const(&)[3]);
      |          ^
p426.cpp:35:2: error: expected constructor, destructor, or type conversion before '(' token
   35 | j({42}); // T deduced as int; array bound not considered
      |  ^
p426.cpp:35:7: error: expected unqualified-id before ')' token
   35 | j({42}); // T deduced as int; array bound not considered
      |       ^
p426.cpp:38:2: error: expected constructor, destructor, or type conversion before '(' token
   38 | k({1,2,3}); // error: deduction fails, no conversion from int to Aggr k({{1},{2},{3}}); // OK, N deduced as 3
      |  ^
p426.cpp:38:10: error: expected unqualified-id before ')' token
   38 | k({1,2,3}); // error: deduction fails, no conversion from int to Aggr k({{1},{2},{3}}); // OK, N deduced as 3
      |          ^
p426.cpp:39:53: error: expected constructor, destructor, or type conversion before '(' token
   39 | template<int M, int N> void m(int const(&)[M][N]); m({{1,2},{3,4}}); // M and N both deduced as 2
      |                                                     ^
p426.cpp:39:67: error: expected unqualified-id before ')' token
   39 | template<int M, int N> void m(int const(&)[M][N]); m({{1,2},{3,4}}); // M and N both deduced as 2
      |                                                                   ^
p426.cpp:40:53: error: expected constructor, destructor, or type conversion before '(' token
   40 | template<class T, int N> void n(T const(&)[N], T); n({{1},{2},{3}},Aggr()); // OK, T is Aggr, N is 3
      |                                                     ^
p426.cpp:40:67: error: expected unqualified-id before ',' token
   40 | template<class T, int N> void n(T const(&)[N], T); n({{1},{2},{3}},Aggr()); // OK, T is Aggr, N is 3
      |                                                                   ^
p426.cpp:40:74: error: expected constructor, destructor, or type conversion before ')' token
   40 | template<class T, int N> void n(T const(&)[N], T); n({{1},{2},{3}},Aggr()); // OK, T is Aggr, N is 3
      |                                                                          ^
p426.cpp:45:4: error: expected constructor, destructor, or type conversion before '(' token
   45 |   o({ &f1, &f41 });
      |    ^
p426.cpp:45:18: error: expected unqualified-id before ')' token
   45 |   o({ &f1, &f41 });
      |                  ^
p426.cpp:46:4: error: expected constructor, destructor, or type conversion before '(' token
   46 |   o({ &f1, static_cast<char(*)(char)>(&f41) });
      |    ^
p426.cpp:46:46: error: expected unqualified-id before ')' token
   46 |   o({ &f1, static_cast<char(*)(char)>(&f41) });
      |                                              ^
p426.cpp: In function 'void h(int, float&)':
p426.cpp:58:10: error: no matching function for call to 'g1(int&, float&, const int&)'
   58 |        g1(x, y, z);
      |        ~~^~~~~~~~~
p426.cpp:53:44: note: candidate: 'template<class T1, class ... Types> void g1(Types ..., T1)'
   53 |   template<class T1, class ... Types> void g1(Types ..., T1);
      |                                            ^~
p426.cpp:53:44: note:   template argument deduction/substitution failed:
p426.cpp:58:10: note:   candidate expects 1 argument, 3 provided
   58 |        g1(x, y, z);
      |        ~~^~~~~~~~~
p426.cpp: At global scope:
p426.cpp:75:5: error: redefinition of 'int n1'
   75 | int n1 = f4(i4);
      |     ^~
p426.cpp:66:5: note: 'int n1' previously declared here
   66 | int n1 = f3(5); // calls f<int>(const int&)
      |     ^~
p426.cpp:76:5: error: redefinition of 'int n2'
   76 | int n2 = f4(0);
      |     ^~
p426.cpp:68:5: note: 'int n2' previously declared here
   68 | int n2 = f3(i); // calls f<int>(const int&)
      |     ^~
p426.cpp:77:5: error: redefinition of 'int n3'
   77 | int n3 = g4(i4);
      |     ^~
p426.cpp:70:5: note: 'int n3' previously declared here
   70 | int n3 = g3(i); // calls g<const int>(const volatile int&)
      |     ^~
p426.cpp:77:13: error: cannot bind rvalue reference of type 'const int&&' to lvalue of type 'int'
   77 | int n3 = g4(i4);
      |             ^~
p426.cpp:73:27: note:   initializing argument 1 of 'int g4(const T&&) [with T = int]'
   73 | template <class T> int g4(const T&&);
      |                           ^~~~~~~~~
p426.cpp:93:13: error: class template argument deduction failed:
   93 | A a{i, 0, ip};
      |             ^
p426.cpp:93:13: error: no matching function for call to 'A(const int&, int, int*&)'
p426.cpp:80:5: note: candidate: 'A(T&&, U&&, int*)-> A<T> [with T = const int; U = int]' (near match)
   80 |     A(T&&, U&&, int*);
      |     ^
p426.cpp:80:5: note:   conversion of argument 1 would be ill-formed:
p426.cpp:93:5: error: cannot bind rvalue reference of type 'const int&&' to lvalue of type 'const int'
   93 | A a{i, 0, ip};
      |     ^
p426.cpp:81:3: note: candidate: 'template<class T> A(T&&, int*)-> A<T>'
   81 |   A(T&&, int*);
      |   ^
p426.cpp:81:3: note:   template argument deduction/substitution failed:
p426.cpp:93:13: note:   candidate expects 2 arguments, 3 provided
   93 | A a{i, 0, ip};
      |             ^
p426.cpp:78:27: note: candidate: 'template<class T> A(A<T>)-> A<T>'
   78 | template <class T> struct A {
      |                           ^
p426.cpp:78:27: note:   template argument deduction/substitution failed:
p426.cpp:93:13: note:   mismatched types 'A<T>' and 'int'
   93 | A a{i, 0, ip};
      |             ^
p426.cpp:90:20: note: candidate: 'template<class T> A(T&&, int*)-> A<T>'
   90 | template <class T> A(T&&, int*) -> A<T>;
      |                    ^
p426.cpp:90:20: note:   template argument deduction/substitution failed:
p426.cpp:93:13: note:   candidate expects 2 arguments, 3 provided
   93 | A a{i, 0, ip};
      |             ^
p426.cpp:105:13: warning: direct base 'X<>' inaccessible in 'E' due to ambiguity [-Winaccessible-base]
  105 |      struct E : X<>, X<int> {};
      |             ^
```

## 検討事項(agenda)
コンパイルエラーを取るか、コンパイルエラーの理由を解説する。

<!-- リンクエラーの解説をする。clang++とg++の比較。意味のある出力。
コンパイルエラーを取るか、コンパイルエラーの理由を解説する。-->


# 参考資料(reference)

cpprefjp - C++日本語リファレンス

https://cpprefjp.github.io/

コンパイラの実装状況

https://cpprefjp.github.io/implementation-status.html


typedef は C++11 ではオワコン

https://qiita.com/Linda_pp/items/44a67c64c14cba00eef1

C99からC++14を駆け抜けるC++講座

https://qiita.com/yumetodo/items/e49a673afd9a3ecb81a8

## 自己参照(self reference)

コピペコンパイルエラーあるある

https://qiita.com/kaizen_nagoya/items/29c832de9d762aed2761

C++ Error Message Collection(1)does not name a type, 11 articles

https://qiita.com/kaizen_nagoya/items/acb9f1a9b5aad6df06bd

dockerにclang

https://qiita.com/kaizen_nagoya/items/8829ffeee397eda50e80

docker gnu(gcc/g++) and llvm(clang/clang++)

https://qiita.com/drafts/059874ea39c4de64c0f7

コンパイル用shell script C版(clangとgcc)とC++版(clang++とg++)

https://qiita.com/kaizen_nagoya/items/74220c0577a512c2d7da

Compare the contents of C++N4910:2022, C++N4741:2018 and C++N4606:2015

https://qiita.com/kaizen_nagoya/items/483246d40f98abff7ded

C++ sample list

https://qiita.com/kaizen_nagoya/items/54ad75b73825b7c04f86


clang++, g++コンパイルエラー方針の違いの例

https://qiita.com/kaizen_nagoya/items/ea6e5009fe126d270a82

astyle 使ってみた

https://qiita.com/kaizen_nagoya/items/3c9a87a781d53a1a23f3

C++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

C++2003とC++2017でコンパイルエラーになるならない事例集
https://qiita.com/kaizen_nagoya/items/a13ea3823441c430edff

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

cpprefjpのdecltypeをコンパイル試験
https://qiita.com/kaizen_nagoya/items/090909af702f0d5d8a67

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


 ＜この記事は個人の過去の経験に基づく個人の感想です。現在所属する組織、業務とは関係がありません。＞

# 文書履歴(document history)
ver. 0.01 初稿 　20220706