2017-07-08 10 views
4

私はテンプレートに新しくはありませんでしたが、私が作業しているデータシリアライザのテンプレート型をコンポーネントに分ける必要がある、説明するのは難しいので、私はそれを実証しました。テンプレートのインスタンス化に失敗しました:コンパイラが不適切なオーバーロード機能を選択しました

私の単純化された問題の例は、example.cppです。

template<typename T> void foo(T& arg) { } 
template<typename T, typename V> void foo(T<V>& arg) { } 

int main(int argc, char *argv[]) 
{ 
    foo(argc); 
    return 0; 
} 

私は、エラーとそれらの一方のみが適切であるとき、両方機能をインスタンス化しようとして示しているようだ警告が表示されます。

$ g++ -Wall -W example.cpp 
example.cpp:2:43: error: ‘T’ is not a template 
template<typename T, typename V> void foo(T<V>& arg) { } 
             ^
example.cpp: In instantiation of ‘void foo(T&) [with T = int]’: 
example.cpp:6:11: required from here 
example.cpp:1:34: warning: unused parameter ‘arg’ [-Wunused-parameter] 
template<typename T> void foo(T& arg) { } 
            ^~~ 

私の問題を解決する方法やこの混乱を防ぐ方法に関する提案はありますか?

+1

誰もが、あなたの問題を生じ*最小限の*完全な例の縮図を投稿するためのおかげで、それを言及していません。あなたがそれを最小限に抑えることができたなら、私はどのように見えません。よく紹介されています。 – WhozCraig

答えて

7

テンプレートテンプレートパラメータ(それ自体が推定可能なテンプレートであるパラメータ)には、使用する構文とは異なる構文が必要です。あなたが書いたように、コンパイラはTがテンプレートであるとは思わないので、構文T<V>は意味をなさない。

template< template<class> class T, class V> void foo(T<V>& arg>) 

が正しい例です。場合

#include <iostream> 

template<typename T> void foo(T& arg) 
{ 
    std::cout << __PRETTY_FUNCTION__ << '\n'; 
} 

template<template<class> class T, class V> void foo(T<V>& arg) 
{ 
    std::cout << __PRETTY_FUNCTION__ << '\n'; 
} 


template<class T> 
struct Bar 
{ 

}; 

int main(int argc, char *argv[]) 
{ 
    foo(argc); 

    Bar<int> bar; 
    foo(bar); 

    return 0; 
} 

出力

void foo(T &) [T = int] 
void foo(T<V> &) [T = Bar, V = int] 
+0

簡単な質問: '__PRETTY_FUNCTION__'はどこに定義されていますか? –

+1

@FrancisCuglerそれはgcc/clangのことです。コンパイラ提供のマクロ。 – WhozCraig

+0

ああ大丈夫です。 MSVCを使っているので、 '__FUNCTION__'を守らなければならないだろうと推測しますが、わからないのと同等のものがない限り、' foo'と同じ名前しか与えません。 –

関連する問題