7

テンプレートと構造体を使用しようとしましたが、機能しません。いろいろ調べましたが、解決策が見つかりません。

#include <iostream>

using namespace std;

template<struct S>
int add(S s) {
    return s.num + s.num2;
}

int main() {

    struct {
        int num = 10;
        int num2 = 20;
    } test;

    cout << add(test) << endl;
    return 0;
}

gcc のエラーは次のとおりです。

test.cpp:5:17: error: ‘struct S’ is not a valid type for a template non-type parameter
test.cpp: In function ‘int add(S)’:
test.cpp:6:5: error: ‘s’ has incomplete type
test.cpp:5:17: error: forward declaration of ‘struct S’
test.cpp: In function ‘int main()’:
test.cpp:13:19: warning: non-static data member initializers only available with -std=c++11 or -std=gnu++11 [enabled by default]
test.cpp:14:20: warning: non-static data member initializers only available with -std=c++11 or -std=gnu++11 [enabled by default]
test.cpp:17:21: error: no matching function for call to ‘add(main()::<anonymous struct>&)’
test.cpp:17:21: note: candidate is:
test.cpp:6:5: note: template<<declaration error> > int add(S)
test.cpp:6:5: note:   template argument deduction/substitution failed:
test.cpp:17:21: note:   cannot convert ‘test’ (type ‘main()::<anonymous struct>’) to type ‘S’
4

5 に答える 5

8

ここではキーワードを使用できませんstructclassorを使用typenameします (ただし、テンプレートをインスタンス化することもできますstruct)。

編集:あなたの他の問題は、の匿名structに関係していmainます。頭のてっぺんからルールを思い出すことはできません (おそらく他の誰かが説明できるでしょう) が、とにかくこれは非常に奇妙な方法なので、動作するバージョンを提供します: http://ideone.com/VGIogH

やや関連:テンプレート引数として匿名の構造体を使用できますか?

もう一度編集: 最初に書いたもので、(テンプレートで置き換えた後) 匿名structで動作しますが、なしでは動作しません(つまり、c++03)。mainstruct--std=c++11

于 2012-11-26T15:57:21.760 に答える
6

C++ では、デフォルトのアクセス指定子が前者と後者にあることを除いて、astructと aclassは基本的に同じものです。一方、テンプレート型の引数を定義するための構文では、 または のいずれかのキーワードを使用する必要があります(オブジェクト指向の意味でのクラスと混同しないでください。任意の型にすることができます)。publicprivateclasstypenameclass

template <typename S>          // equivalently class S
int add(S s) ...
于 2012-11-26T15:58:25.730 に答える
1

さらに、テンプレートで構造体を typename に置き換えることに加えて、私のコンパイラ (GCC) は、構造体メンバーを直接初期化することはできないと言っているので、次のようにすることができます。

#include <iostream>

using namespace std;

template<typename S>
int add(S s) {
   return s.num + s.num2;

}

int main() {

   struct {
       int num;
       int num2;
   } test;

   test.num = 10;
   test.num2 = 20;

   cout << add(test) << endl;
   return 0;
}

編集:テンプレートに構造体を知らせる必要があります:

#include <iostream>

using namespace std;

struct MyStruct {
   int num;
   int num2;
};
template<typename S>
int add(S s) {
   return s.num + s.num2;

}

int main() {

   MyStruct test;

   test.num = 10;
   test.num2 = 20;

   cout << add(test) << endl;
   return 0;
}
于 2012-11-26T16:07:27.217 に答える
1

あなたの問題は、誰かが書いているのを見たことがあるということです:

template<class A>
bool foo( A* a ) { 
  return *a;
}

または似たようなもので、それclassは A が でなければならないことを意味すると考えましたclass

ここで実際に起こっていることは、C++ の構文が時々最悪だということです。テンプレートが最初に作成されたときclass、テンプレート引数リストでキーワード ( ) を再利用して、テンプレートに渡すことができる他のもの ( などint) とは対照的に、「型」を意味しました。

これは非常に紛らわしい構文です。たまたま、これは上記と同等です。

template<typename A>
bool foo( A* a ) {
  return *a;
}

ただし、 A が任意の型になり得ることがより明確になります。

ただし、テンプレート パラメーターで「型」を指定する適切な方法だった頃から、多くの C++ コードがぶら下がってclassいるため、C++ では引き続き許可されています。

于 2012-11-26T16:55:57.493 に答える
-2

匿名型では機能せず、関数呼び出しで型を指定する必要があります。

#include <iostream>

using namespace std;

template<typename S>
int add(S s) {
    return s.num + s.num2;
}

int main() {

    struct A {
        int num = 10;
        int num2 = 20;
    } test;

    cout << add<A>(test) << endl;
    return 0;
}
于 2012-11-26T15:59:22.507 に答える