1
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?

C++ "オブジェクト.template method<型>( )" の意味がわからなかったので調べてみた(dot template)

Last updated at Posted at 2025-04-04

概要

C++の線形代数ライブラリであるEigenのドキュメントのExampleをいろいろと試していたところ、以下のコードが出てきた。

#include <iostream>
#include <Eigen/Dense>
 
int main()
{
   Eigen::MatrixXf A = Eigen::MatrixXf::Random(3, 2);
   std::cout << "Here is the matrix A:\n" << A << std::endl;
   Eigen::VectorXf b = Eigen::VectorXf::Random(3);
   std::cout << "Here is the right hand side b:\n" << b << std::endl;
   std::cout << "The least-squares solution is:\n"
        << A.template bdcSvd<Eigen::ComputeThinU | Eigen::ComputeThinV>().solve(b) << std::endl;
}

最後の文

A.template bdcSvd<Eigen::ComputeThinU | Eigen::ComputeThinV>().solve(b)

が全く理解できずにいたが、さらにコンパイルエラーにもなったので記載ミスかとも思ったが調べてみることにした。.templatedot templateと言うみたいです。

追記)
コメント欄に@SaitoAtsushiさんの解説がありますので、コメント欄も御覧ください。

実行環境

> g++ --version
Apple clang version 16.0.0 (clang-1600.0.26.6)
Target: arm64-apple-darwin24.3.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin

dot templateの調査

参照記事

実験

参照記事の2番目のサンプルコードに出力のコード追加して試してみます。

test1.cc
#include <iostream>
#include <vector>

struct X {
  template <int N>
  int get() const
  {
      return N;
  }
};

int main()
{
  typename std::vector<int>::iterator it; // OK

  int value = X().template get<3>(); // OK
  std::cout << "value = " << value << std::endl;
}

記事はC++11のところに記載されていたので、C++11以上なら大丈夫なようです。

> g++ test1.cc -std=c++11
> ./a.out
value = 3

上記のコードを今までのように書くとしたら、以下のようになるでしょう。

test2.cc
#include <iostream>
#include <vector>

struct X {
  template <int N>
  int get() const
  {
      return N;
  }
};

int main()
{
  std::vector<int>::iterator it;

  int value = X().get<3>(); 
  std::cout << "value = " << value << std::endl;
}
> g++ test2.cc -std=c++03
> ./a.out
value = 3

C++03でもコンパイルエラーはなかった。

今度はtemplateを使った関数printの中で試す。

test3.cc
#include <iostream>
#include <vector>

struct X {
  template <int N>
  int get() const
  {
      return N;
  }
};


template<typename T> void print(T& x) {
  int value = x.get<3>(); 
  std::cout << "value = " << value << std::endl;
}

int main()
{
  typename std::vector<int>::iterator it; 
  X xx  = X();
  print<X>(xx);
}
> g++ test3.cc -std=c++11
test3.cc:14:17: error: missing 'template' keyword prior to dependent template name 'get'
   14 |   int value = x.get<3>(); 
      |                 ^  ~~~
1 error generated.

エラーになりました。
では、dot templateに戻してみます。

test4.cc
#include <iostream>
#include <vector>

struct X {
  template <int N>
  int get() const
  {
      return N;
  }
};


template<typename T> void print(T& x) {
  int value = x.template get<3>();
  std::cout << "value = " << value << std::endl;
}

int main()
{
  typename std::vector<int>::iterator it;
  X xx = X();
  print<X>(xx);
}
> g++ test4.cc -std=c++11
> ./a.out
value = 3

dot templateなら無事にコンパイルできました。

もう一つだけ試してみます。

test5.cc
#include <iostream>
#include <vector>

struct X {
  template <int N>
  int get() const
  {
      return N;
  }
};


template<typename T>T print(X& x) {
  int value = x.get<3>();
  std::cout << "value = " << value << std::endl;
  return (T)value;
}

int main()
{
  typename std::vector<int>::iterator it;
  X xx = X();
  print<int>(xx);
}

Ttemplateはなくても良かったのですが、一応残しました。

> g++ test5.cc -std=c++11
> ./a.out
value = 3

今までの使い方も確認できて良かったです。

templateで指定された型のオブジェクトのメンバーにtemplateが使われているときは
dot templatを使わないといけないのではないか、というのが自分なりの理解です。たぶん、これは1番目の参照記事が言っている事だとは思います。

終わりに

最初検索などをしてもtemplateで検索するとたくさん出てくるので、自分が知りたいものがdot templateだと分かるまでに時間がかかりました。さらに、dot templateの記事も少ないという状況でした。

1
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
1
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?