如何将模板实例传递给另一个模板的另一个实例?
How to pass instance of template to another instance of another template?
我有两个class模板必须是模板(C++)。我只是简化了他们的代码以显示问题的本质。如何将对象 (obj1
) 从一个模板 (MyClass1
) 传递到第二个模板 (MyClass2
) 的另一个对象 (obj2
)?我试过模板参数和构造函数,但我仍然有编译错误。如何正确地做到这一点?重要的是,我不知道模板参数,因此解决方案具有通用性,而不是针对指定参数。对象应该通过指针或引用传递,我不需要它的副本。
template<int a, int b>
class MyClass1 {
public:
MyClass1() {
// Do something...
}
int foo(int x) {
return a * x + b;
}
};
template<double m, double n>
class MyClass2 {
public:
MyClass2() {
// Do something
}
double bar(int x) {
// Do something with x using object of MyClass1 and then with m...
}
double zet(int x) {
// Do something with x using object of MyClass1 and then with n...
}
};
int main() {
MyClass1<4, 3> obj1;
MyClass2<3.14, 2.56> obj2; // <-- How to pass obj1 here???
// Maybe that way?: MyClass2<3.14, 2.56, obj1> obj2;
// Or that way?: MyClass2<3.14, 2.56> obj2(obj1);
obj1.foo(12);
obj2.bar(1.234);
obj2.zet(5.678);
}
我不确定这是否与此问题相关,但我正在使用标准设置在 Atmel Studio 7 中为 AVR 编写 C++ 代码。
您的代码无法使用 C++11 进行编译,原因如下:
A non-type template parameter must have a structural type, which is
one of the following types (optionally cv-qualified, the qualifiers
are ignored):
- lvalue reference type (to object or to function);
- an integral type;
- a
pointer type (to object or to function);
- a pointer to member type (to
member object or to member function);
- an enumeration type;
- std::nullptr_t; (since C++11)
- a floating-point type; (since C++20)
关于你的核心问题,你可以这样做:
template<int m, int n, typename Obj1Type>
class MyClass2 {
Obj1Type obj1_;
public:
MyClass2() {
// Do something
}
MyClass2(Obj1Type const& obj1) {
obj1_ = obj1;
}
// ...
};
然后在主要部分:
int main() {
MyClass1<4, 3> obj1;
MyClass2<3, 2, MyClass1<4, 3>> obj2(obj1);
obj1.foo(12);
obj2.bar(1);
obj2.zet(5);
}
看看live
更新
您还可以利用继承并为此目的创建一个简单的基础 class:
class BaseMyClass1 {};
template<int a, int b>
class MyClass1 : public BaseMyClass1 {
// ...
};
template<int m, int n>
class MyClass2 {
BaseMyClass1 obj1_;
public:
MyClass2() {
// Do something
}
template <typename Obj1Type>
MyClass2(Obj1Type const& obj1) {
obj1_ = obj1;
}
// ...
};
然后在主要部分:
int main() {
MyClass1<4, 3> obj1;
MyClass2<3, 2> obj2(obj1);
obj1.foo(12);
obj2.bar(1);
obj2.zet(5);
}
这样就省去了在模板参数列表中声明模板的麻烦。但是,这可能不是您的完美解决方案,因为它引入了对象切片。
看看live
模板 class 接受另一个模板 class 作为模板参数。所以你可以为 Myclass2 传递类型名 T。
示例程序:
你可以尝试这样的事情:
#include <iostream>
using namespace std;
template<typename T1>
class Myclass1
{
public:
Myclass1(T1 x):m1_x(x)
{
cout << "Myclass1 C'tor" << m1_x << endl;
}
T1 m1_x;
T1 get_x()
{
return m1_x;
}
};
template < typename T1 >
class Myclass2
{
public:
Myclass2(T1 x): m_x(x)
{
cout << "My class 2 C'tor with value" << m_x.get_x() << endl;
}
public:
T1 m_x;
};
int main()
{
Myclass1 <int > obj1(5000);
Myclass2< Myclass1 <int> > obj2 ( obj1 );
return 0;
}
我有两个class模板必须是模板(C++)。我只是简化了他们的代码以显示问题的本质。如何将对象 (obj1
) 从一个模板 (MyClass1
) 传递到第二个模板 (MyClass2
) 的另一个对象 (obj2
)?我试过模板参数和构造函数,但我仍然有编译错误。如何正确地做到这一点?重要的是,我不知道模板参数,因此解决方案具有通用性,而不是针对指定参数。对象应该通过指针或引用传递,我不需要它的副本。
template<int a, int b>
class MyClass1 {
public:
MyClass1() {
// Do something...
}
int foo(int x) {
return a * x + b;
}
};
template<double m, double n>
class MyClass2 {
public:
MyClass2() {
// Do something
}
double bar(int x) {
// Do something with x using object of MyClass1 and then with m...
}
double zet(int x) {
// Do something with x using object of MyClass1 and then with n...
}
};
int main() {
MyClass1<4, 3> obj1;
MyClass2<3.14, 2.56> obj2; // <-- How to pass obj1 here???
// Maybe that way?: MyClass2<3.14, 2.56, obj1> obj2;
// Or that way?: MyClass2<3.14, 2.56> obj2(obj1);
obj1.foo(12);
obj2.bar(1.234);
obj2.zet(5.678);
}
我不确定这是否与此问题相关,但我正在使用标准设置在 Atmel Studio 7 中为 AVR 编写 C++ 代码。
您的代码无法使用 C++11 进行编译,原因如下:
A non-type template parameter must have a structural type, which is one of the following types (optionally cv-qualified, the qualifiers are ignored):
- lvalue reference type (to object or to function);
- an integral type;
- a pointer type (to object or to function);
- a pointer to member type (to member object or to member function);
- an enumeration type;
- std::nullptr_t; (since C++11)
- a floating-point type; (since C++20)
关于你的核心问题,你可以这样做:
template<int m, int n, typename Obj1Type>
class MyClass2 {
Obj1Type obj1_;
public:
MyClass2() {
// Do something
}
MyClass2(Obj1Type const& obj1) {
obj1_ = obj1;
}
// ...
};
然后在主要部分:
int main() {
MyClass1<4, 3> obj1;
MyClass2<3, 2, MyClass1<4, 3>> obj2(obj1);
obj1.foo(12);
obj2.bar(1);
obj2.zet(5);
}
看看live
更新
您还可以利用继承并为此目的创建一个简单的基础 class:
class BaseMyClass1 {};
template<int a, int b>
class MyClass1 : public BaseMyClass1 {
// ...
};
template<int m, int n>
class MyClass2 {
BaseMyClass1 obj1_;
public:
MyClass2() {
// Do something
}
template <typename Obj1Type>
MyClass2(Obj1Type const& obj1) {
obj1_ = obj1;
}
// ...
};
然后在主要部分:
int main() {
MyClass1<4, 3> obj1;
MyClass2<3, 2> obj2(obj1);
obj1.foo(12);
obj2.bar(1);
obj2.zet(5);
}
这样就省去了在模板参数列表中声明模板的麻烦。但是,这可能不是您的完美解决方案,因为它引入了对象切片。
看看live
模板 class 接受另一个模板 class 作为模板参数。所以你可以为 Myclass2 传递类型名 T。 示例程序: 你可以尝试这样的事情:
#include <iostream>
using namespace std;
template<typename T1>
class Myclass1
{
public:
Myclass1(T1 x):m1_x(x)
{
cout << "Myclass1 C'tor" << m1_x << endl;
}
T1 m1_x;
T1 get_x()
{
return m1_x;
}
};
template < typename T1 >
class Myclass2
{
public:
Myclass2(T1 x): m_x(x)
{
cout << "My class 2 C'tor with value" << m_x.get_x() << endl;
}
public:
T1 m_x;
};
int main()
{
Myclass1 <int > obj1(5000);
Myclass2< Myclass1 <int> > obj2 ( obj1 );
return 0;
}