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

您不能在struct此处使用关键字。使用classor typename(您仍然可以使用 a 实例化您的模板struct)。

编辑:您的其他问题structmain. 不记得我脑海中的规则(也许其他人可以解释它们),但无论如何这是一种非常奇怪的做事方式,所以我只提供一个工作版本:http: //ideone.com/VGIogH

有点相关:我们可以有一个匿名结构作为模板参数吗?

再次编辑:您最初写的内容,匿名作品(在模板中替换后)带有struct,但不是没有(即c ++ 03)。mainstruct--std=c++11

于 2012-11-26T15:57:21.760 回答
6

在 C++ 中,astruct和 aclass基本相同,只是默认访问说明符public在前者和private后者中。另一方面,定义模板类型参数的语法需要使用classortypename关键字(不要class在这里与 OO 意义上的混淆,它可以是任何类型)。

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

除了在模板中用 typename 替换 struct 之外,我的编译器(GCC)说你不能直接初始化你的 struct 成员,所以你可以这样做:

#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在模板参数列表中重用关键字 ( ) 来表示“类型”,而不是您可以传递给模板的其他内容(例如 an 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 回答