2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

可変長テンプレート引数のそれぞれの値に関数を適用する

Last updated at Posted at 2015-11-03

可変長のデータに対して同一関数を適用したい。
いまだと可変長テンプレート引数を使うのかなと思って次のようにしてみた。

http://lnseab.hatenablog.jp/entry/2012/12/13/172753 のテンプレートパックの展開を参考にして次のようなものを書いた。

expand-variadic-templates.cpp
#include <iomanip>
#include <iostream>
#include <utility>
#include <cstdio>

// clang needs non-void type for template pack
template <typename T>
int log(T target) noexcept {
    time_t const now = std::time(nullptr);
    std::tm const * timeinfo = std::localtime(&now);
    std::cout
        << std::setfill('0')
        << "["
        << timeinfo->tm_year + 1900
        << "/"
        << std::setw(2) << timeinfo->tm_mon + 1
        << "/"
        << std::setw(2) << timeinfo->tm_mday
        << " "
        << std::setw(2) << timeinfo->tm_hour
        << ":"
        << std::setw(2) << timeinfo->tm_min
        << ":"
        << std::setw(2) << timeinfo->tm_sec
        << "] "
        << target
        << std::endl;
    return 0;
}

// clang consexpr needs a literal type for return value
template <typename ... Args>
inline constexpr int expand_variadic_templates(Args ... args) noexcept {
    return 0;
}

// clang consexpr needs a literal type for return value
template <typename ... Args>
inline constexpr int log_all(Args ... args) noexcept {
    return expand_variadic_templates(log(args)...);
}

int main(const int argc, const char* const argv[]) {
    log_all(1, 0.2, "foo", true);

    return 0;
}

gcc/clang で -Wunused-parameter コンパイラーオプションを指定していると expand_variadic_templates で使わない仮引数が生成されて警告が出てしまうのでそこだけ注意かな。

渡す値の型がすべて同じ場合、 http://cpplover.blogspot.jp/2010/03/variadic-templates.html で紹介されてる再帰の方法も使えるけどスマートではないね。

同じことを再帰で処理することもできる。コメントで指摘してくださった amate さんありがとうございます。あれ ? これでいいんじゃね ?

recursive-variadic-templates.cpp
inline constexpr int log_all() noexcept {
    return 0;
}

template <typename T, typename ... Args>
inline void log_all(T target, Args ... rest) noexcept {
    log(target);
    log_all(rest...);
}

int main(const int argc, const char* const argv[]) {
    log_all(1, 0.2, "foo", true);

    return 0;
}

2
0
2

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
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?