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.

ポインタをテンプレート引数にする

Posted at

先日の yhpg の懇親会で、関数へのポインタをテンプレート引数にできるという話を聞いた。
私はてっきり無理だと思っていたんだけど、テンプレートの黎明期からできた模様:

このほかの template-arg は、 constant-expression(定数式)であるか、外部リンケージのオブジェクトや関数、あるいは静的クラス・メンバのアドレスでなければならない。

( 注解 C++リファレンスマニュアル p430 )

知らなかった。

まあ知っていても使う機会はなかなかなさそうではあるけれど。

関数へのポインタをテンプレート引数にする

例えば以下のような感じ。

ptrtemplate1.cpp
// clang++ -std=c++11 ptrtemplate1.cpp
# include <iostream>

template< char const *func()>
void foo()
{
  std::cout << "FOO[" << func() << "]\n";
}

char const * bar()
{
  return "bar";
}

int main()
{
  foo<bar>(); //=> FOO[bar]
}

グローバル変数へのポインタをテンプレート引数にする

グローバル変数へのポインタはテンプレート引数にできるが、ローカルな変数はテンプレート引数にできない。
以下の通り:

ptrtemplate2.cpp
// clang++ -std=c++11 ptrtemplate2.cpp
# include <iostream>

char const * bar = "bar";

template< char const ** str >
void foo()
{
  std::cout << "FOO[" << *str << "]\n";
}

int main()
{
  foo<&bar>(); //=> FOO[bar]
  char const * baz = "baz";
  foo<&baz>(); //=> エラー。
}

メンバへのポインタをテンプレート引数にする

注解 C++リファレンスマニュアル の記述からはわからないが、メンバへのポインタもテンプレート引数にすることができる。
以下の通り:

ptrtemplate3.cpp
// clang++ -std=c++11 ptrtemplate3.cpp
# include <iostream>

struct Hoge
{
  char const * fuga;
  char const * piyo;
};

Hoge hoge()
{
  return { "fuga", "piyo" };
}

template< char const * Hoge::*m >
void foo()
{
  std::cout << "FOO[" << (hoge().*m) << "]\n";
}

int main()
{
  foo<&Hoge::fuga>(); //=> Foo[fuga]
  foo<&Hoge::piyo>(); //=> Foo[piyo]
}

いずれも

いずれも、なかなか使い所のない機能だと思う。

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