1

今、関数テンプレートを学習しています。関数テンプレートのインスタンス化に関する少しのルールを調べたいと思っていました。だから私は、次のコードを書いている:C++ - 関数テンプレートのインスタンス化に関するルール

#include <iostream> 

template <typename> 
int check(int x) { 
    return x * 2; 
} 

int main() { 
    std::cout << check<double>(10) << std::endl; // #1 
    std::cout << check<>(10) << std::endl;   // #2 
    std::cout << check(10) << std::endl;   // #3 
    return 0; 
} 

ライン#1、#2、#3は、それぞれが、私はどちらか一方のみのを残して、残りをコメントしてみてください、すべて一緒にコンパイルされていません。 #1を有効にすると、コンパイルエラーがなく、正しい回答 "20"が表示されます。私が理解しているように、"チェック<"ダブル ">"は、"int check(int)"関数が実際に作成された(テンプレートパラメータの型は影響を与えません)。 #3が有効な場合、私はコンパイルエラーを持っています "エラー:を呼び出しようとしているので、" check(int) ""の呼び出しで一致する関数がありません "存在しない関数です。私の質問は#2のケースに関する:この場合、私は同じ"エラー: 'check(int)'"の呼び出しのための一致する関数がありません。 "check <>(10)"トリガーテンプレートのインスタンシエーションメカニズムも呼び出さないでください。

+0

"チェック<>(10)"テンプレートのインスタンス化メカニズムもトリガーしないでください?_ "あなたの質問に対する答えは:どのような引数ですか? – curiousguy

答えて

0

テンプレート引数を渡さないと、テンプレート引数なしの関数を探すことになります(つまり、テンプレートをインスタンス化しません)。追加された<>は、オーバーロードがないため、この場合は何も意味しません。

あなたが持っている機能は、実際にこのようにタイプTを推測することはできません何もコンパイラ用のテンプレートを使用していますが、あなたはこのようにそれを書いた場合はありませんので:すべての3例次に

template <typename T> 
T check(T x) { 
    return x * 2; 
} 

ますそれはタイプTを推測しているからです。詳細は、https://stackoverflow.com/a/797632/888641を参照してください。

注:typenameまたはclassを使用できますが、ここではまったく同じことを行います。

+0

ありがとう!私が "<>"を追加したのは、Vandevoordeの "C++ Templates:Complete Guilde"の本で、 "check <>"のような呼び出しが関数のテンプレート版を強制的に使用するように書かれているからです(関数テンプレートオーバーロード) – mkostya

+0

何も意味しません。オーバーロードがあった場合は、そうでなければ一致するオーバーロードの代わりにテンプレートが優先されます。 –

+0

もし過負荷がなければ何も意味しませんか? – mkostya

0

私は通常、テンプレートがそのように行かないことを言っている:(

は、このいずれかを試してみてください:テンプレート引数を推定することができれば

template<typename T> 
T check(T x){ 
    return x*2; 
} 
0

#2は有効だろう

#include <iostream> 

template <class T> 
void foo(T t) 
{ 
    std::cout << "Template " << t << '\n'; 
} 

void foo(int n) 
{ 
    std::cout << "Not template " << n << '\n'; 
} 

int main() 
{ 
    foo(10); //calls non-template function 
      //because matching non-template preferred over function templates 

    foo<>(10); //calls the template function, empty brackets indicate you want 
       //the template overload, type is deduced from passed argument. 

} 

関数テンプレートにデフォルトの引数がある場合は、別の可能性があります(C++ 11でのみ有効です)。

あなたが買ってあげる
template <class T = void> 
int foo() 
{ 
    return 10; 
} 

int main() 
{ 
    return foo<>(); //same as foo<void>(); 
} 
+0

ありがとう、これはそれを明確にします。 – mkostya

0

だけテンプレートインスタンスは、他の人がテンプレートをインスタンス化していない

check<double>(10) 

です。

template<typename T> 
T check(T x) { 
    return x*2; 
} 

は、次にテンプレート引数控除の力を使ってあなたはあなたがいない

check(10.0); // instantiates check<dobule> 
check(3);  // instantiates check<int> 

または

a = MyObject(); 
check(a);   // instantiates check<MyObject> 
1

を呼び出すことができるようにも、関数テンプレートのフルパワーのためのテンプレート引数を含めます任意のテンプレートパラメータを<>に入れてください。コンパイラは、どのテンプレート関数をインスタンス化するかをどのように知ることができますか?テンプレート機能があることに注意してください:

template <typename> 
int check(int x) 

あなたはこのように変更した場合:

template <typename T> 
int check(T x) 

その後、<>(10)をチェックコンパイラは、パラメータからタイプを知ることができるので、問題ないはずです。