10
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

C言語でマクロで作成していた機能をtemplateで作るために、
可変長引数templateを勉強し始めました。

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

可変引数テンプレート1

のプログラムを入力して編纂(compile)してみます。

temp.cpp
#include <iostream>
#include <cstdlib>

template <class... Args>
struct X {
  // パラメータパックを ... で展開して、
  // std::tupleクラステンプレートの引数として渡す
  std::tuple<Args...> values;
};

void g(int, char, const std::string&) {}

template <class... Args>
void f(Args... args)
{
  // パラメータパックを ... で展開して、
  // 関数g()の引数として渡す
  g(args...);
}

int main (){
f(3, 'a', "hello");
return EXIT_SUCCESS;
}

Xcodeのclang++でコンパイルするとエラーが出た。

$ clang++ temp.cpp
temp.cpp:4:16: warning: variadic templates are a C++11 extension
      [-Wc++11-extensions]
template <class... Args>
               ^
temp.cpp:8:8: error: no type named 'tuple' in namespace 'std'
  std::tuple<Args...> values;
  ~~~~~^
temp.cpp:8:13: error: expected member name or ';' after declaration specifiers
  std::tuple<Args...> values;
  ~~~~~~~~~~^
temp.cpp:13:16: warning: variadic templates are a C++11 extension
      [-Wc++11-extensions]
template <class... Args>
               ^
2 warnings and 2 errors generated.

blew install llvm --with-clang で導入したclang++だとエラーが出なかった。

$ clang++ --version
clang version 6.0.0 (tags/RELEASE_600/final)
Target: x86_64-apple-darwin17.7.0
Thread model: posix
InstalledDir: /usr/local/opt/llvm/bin
$ clang++ temp.cpp -std=c++2a
$ a.out
$ 

何も出力しないプログラムは嬉しくない。

tuple

tuple.cpp
#include <iostream>
#include <tuple>
#include <string>
#include <cstdlib>

using namespace std;

int main()
{
  // 3要素のタプルを作る
  tuple<int, char, std::string> t = std::make_tuple(1, 'a', "hello");

  // 0番目の要素を参照
  int& i = get<0>(t);
  cout << i << endl;

  // 2番目の要素を参照
  string& s = get<2>(t);
  cout << s << endl;

  return EXIT_SUCCESS;
}

Xcodeのclang++でコンパイルするとエラーが出た。

$ clang++ tuple.cpp
tuple.cpp:11:3: error: use of undeclared identifier 'tuple'
  tuple<int, char, std::string> t = std::make_tuple(1, 'a', "hello");
  ^
tuple.cpp:11:12: error: expected
      '(' for function-style cast or type construction
  tuple<int, char, std::string> t = std::make_tuple(1, 'a', "hello");
        ~~~^
tuple.cpp:14:19: error: use of undeclared identifier 't'
  int& i = get<0>(t);
                  ^
tuple.cpp:18:22: error: use of undeclared identifier 't'
  string& s = get<2>(t);
                     ^
4 errors generated.

blew install llvm --with-clangで導入したclang++だとエラーが出なかった。

$ clang++ tuple.cpp
$ ./a.out
1
hello

出力があると確認しやすい。

可変引数テンプレート2

https://cpprefjp.github.io/lang/cpp11/variadic_templates.html
の2つめのプログラム。
using namespace std;などを追加。

temp2.cpp
#include <iostream>
#include <utility>
#include <cstdlib>

using namespace std;

// パラメータパックが空になったら終了
void print() {}

// ひとつ以上のパラメータを受け取るようにし、
// 可変引数を先頭とそれ以外に分割する
template <class Head, class... Tail>
void print(Head&& head, Tail&&... tail)
{
  cout << head << endl;

  // パラメータパックtailをさらにheadとtailに分割する
  print(move(tail)...);
}

int main()
{
  print(1, 'a', "hello");
  return EXIT_SUCCESS;
}
$ clang++ temp2.cpp
$ ./a.out
1
a
hello

可変引数テンプレート関数

amowwee.cpp
#include <iostream>
#include <tuple>
#include <string>
#include <cstdlib>

using namespace std;

template <class... Args>
void func(Args... args)
{
    // sizeof...で可変引数にいくつ変数を持っているか調べる
    std::cout << sizeof...(args) << std::endl;
    // argsはそのままでは使えない
    // std::cout << args << std::endl;    // compile error
}

int main()
{
    func("foo", "bar", "hoge", "huga");    // 4
    func();    // 0, ...Argsは引数無しでもOK
    return EXIT_SUCCESS;
}

Xcodeのclang++では警告が出た。

$ clang++ amowwee.cpp 
amowwee.cpp:8:16: warning: variadic templates are a C++11 extension
      [-Wc++11-extensions]
template <class... Args>
               ^
1 warning generated.
$ ./a.out
4
0

blew install llvm --with-clangで導入した方は警告もない。

clang++ amowwee.cpp -Wall
$ ./a.out
4
0

vc++でも全部コンパイルしてみた。/EHscのコンパイルスイッチをつければ警告なし。実行結果は同じ。

被引用算譜(referenced program)

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

参考文献(reference)

LLVMソースコードのコンパイルをしようと思ってハマった罠とそこから脱出するための努力
https://qiita.com/kaizen_nagoya/items/16f270e42b947756ced3

可変長template引数でネスト機能付きタスクリストを作る
https://qiita.com/unsolvedprobrem/items/a77f3e9a856af2f83ba3

C++のパラメータパック基礎&パック展開テクニック
https://qiita.com/_EnumHack/items/677363eec054d70b298d

可変長テンプレート引数のそれぞれの値に関数を適用する
https://qiita.com/janus_wel/items/de793bcd2aa845e3e8cc
C++ Support(0) 
https://qiita.com/kaizen_nagoya/items/8720d26f762369a80514

Coding Rules(0) C Secure , MISRA and so on
https://qiita.com/kaizen_nagoya/items/400725644a8a0e90fbb0

Ethernet 記事一覧 Ethernet(0)
https://qiita.com/kaizen_nagoya/items/88d35e99f74aefc98794

Wireshark 一覧 wireshark(0)、Ethernet(48)
https://qiita.com/kaizen_nagoya/items/fbed841f61875c4731d0

線網(Wi-Fi)空中線(antenna)(0) 記事一覧(118/300目標)
https://qiita.com/kaizen_nagoya/items/5e5464ac2b24bd4cd001

OSEK OS設計の基礎 OSEK(100)
https://qiita.com/kaizen_nagoya/items/7528a22a14242d2d58a3

Error一覧(C/C++, python, bash...) Error(0)
https://qiita.com/kaizen_nagoya/items/48b6cbc8d68eae2c42b8

なぜdockerで機械学習するか 書籍・ソース一覧作成中 (目標100)
https://qiita.com/kaizen_nagoya/items/ddd12477544bf5ba85e2

言語処理100本ノックをdockerで。python覚えるのに最適。:10+12
https://qiita.com/kaizen_nagoya/items/7e7eb7c543e0c18438c4

プログラムちょい替え(0)一覧:4件
https://qiita.com/kaizen_nagoya/items/296d87ef4bfd516bc394

TOPPERSまとめ #名古屋のIoTは名古屋のOSで
https://qiita.com/kaizen_nagoya/items/9026c049cb0309b9d451

docker(0) 資料集
https://qiita.com/kaizen_nagoya/items/45699eefd62677f69c1d

Qiita-dockerお宝鑑定団
https://qiita.com/kaizen_nagoya/items/509e125263559b5aed5b

The C++ Standard Library: clang++とg++でコンパイルしてみた(まとめ):14件
https://qiita.com/kaizen_nagoya/items/9bdfaa392443d13e5759

C++17 - The Complete Guide clang++とg++でコンパイルしてみた(まとめ):4件
https://qiita.com/kaizen_nagoya/items/c000f307e642990781e1

C++N3242, 2011, ISO/IEC 14882, C++ standard(1) Example code compile list
https://qiita.com/kaizen_nagoya/items/685b5c1a2c17c1bf1318

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

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

C++N4910:2022 Standard Working Draft on ISO/IEC 14882(0) sample code compile list
https://qiita.com/kaizen_nagoya/items/fc957ddddd402004bb91

Autosar Guidelines C++14 example code compile list(1-169)
https://qiita.com/kaizen_nagoya/items/8ccbf6675c3494d57a76

プログラマによる、プログラマのための、統計と確率のプログラミングとその後 統計と確率一覧(0)
https://qiita.com/kaizen_nagoya/items/6e9897eb641268766909

プログラマが知っていると良い「公序良俗」
https://qiita.com/kaizen_nagoya/items/9fe7c0dfac2fbd77a945

一覧の一覧( The directory of directories of mine.) Qiita(100)
https://qiita.com/kaizen_nagoya/items/7eb0e006543886138f39

小川清最終講義、小川清最終講義(再)計画, Ethernet(100) 英語(100) 安全(100)
https://qiita.com/kaizen_nagoya/items/e2df642e3951e35e6a53

<この記事は個人の過去の経験に基づく個人の感想です。現在所属する組織、業務とは関係がありません。>
This article is an individual impression based on the individual's experience. It has nothing to do with the organization or business to which I currently belong.

文書履歴(document history)

ver. 0.10 初稿 20180806 午前
ver. 0.11 brew install llvm --with-clangで導入したコンパイラの結果追記 20180806 午後
ver. 0.12 被参照算譜追記 20180807
ver. 0.13 using namespace std;追記 20180808
ver. 0.14 vc++で動作確認 20180809
ver. 0.15 表題変更 20190104

最後までおよみいただきありがとうございました。

いいね 💚、フォローをお願いします。

Thank you very much for reading to the last sentence.

Please press the like icon 💚 and follow me for your happy life.

10
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?