テンプレート関数に対してテンプレート引数を指定する

http://www.geocities.jp/ky_webid/cpp/language/028.html

テンプレートクラスだけでなく、テンプレート関数にもテンプレート引数を設定できます。

template <class T,int NUM> void output(T t) {
    for(int i=0;i<NUM;i++) {
        cout << t << endl;
    }
}

しかし、ここまで書いてみてひとつ疑問に思いました。そもそもテンプレートクラスの場合はインスタンス化する際にクラス名を指定するのでそのときに

CSample<int, 5>

のようにテンプレート引数を指定できるのですが、テンプレート関数の場合はどうするのでしょうか?

// どこでテンプレート引数を渡せばいいの?
output(123);

調べてみたらわかりました。

http://homepage2.nifty.com/well/Template.html

int    iValue2 = Add<int>(2.3, 1);  // ?int Add(int, int) が使われます。

なるほど、関数の場合は明示的に型を示す方法として関数名の後にテンプレート引数を指定するわけなんですね。

ということで最初の話に戻ってテンプレート引数を指定してみます。

#include <iostream>
using namespace std;

template <class T,int NUM> void output(T t) {
    for(int i=0;i<NUM;i++) {
        cout << t << endl;
    }
}

int main() {
    
    output<int, 5>(123);
    
    return 0;
}
$ main
123
123
123
123
123

できました。

ただし一つ注意があります。

最後に、テンプレート引数のデフォルト値は、テンプレートクラスだけにしか指定できず、テンプレート関数には使えません。

理由はわかりませんが、何故かテンプレート関数の場合はテンプレート引数のデフォルト値が使えないみたいです。

// デフォルト値を指定してみる
template <class T,int NUM=1> void output(T t) {
    for(int i=0;i<NUM;i++) {
        cout << t << endl;
    }
}
$ cl /W4 /EHsc main.cpp
Microsoft(R) 32-bit C/C++ Optimizing Compiler Version 15.00.30729.01 for 80x86
Copyright (C) Microsoft Corporation.  All rights reserved.

main.cpp
main.cpp(8) : error C4519: 既定のテンプレートの引数をクラスのテンプレート以外で使用することはできません

と、このようにコンパイルエラーとなりました。

何故使用できないのか理由が知りたいですね。