我对模板有疑问。如何将typename T
传递到class A
中以在class B
中使用它?我只想在class A
中传递typename,但我也需要在class B
中使用它。可能吗?
#include <iostream>
using namespace std;
template <typename T>
class A {
public:
B getObj() { return obj; };
void setObj(B bObj) { obj = bObj; };
private:
B obj;
};
template <typename T>
class B {
public:
T getValue() { return value; };
void setValue(T val) { value = val; };
private:
T value = 0;
};
int main() {
A<int> a;
a.setObj(B()); // Is it possible to write B without typename every time?
cin.get();
return 0;
}
此代码编译时出现以下错误:
error C3646: 'getObj': unknown override specifier
note: see reference to class template instantiation 'A<T>' being compiled
error C2059: syntax error: '('
error C2334: unexpected token(s) preceding '{'; skipping apparent function body
error C2061: syntax error: identifier 'B'
error C3646: 'obj': unknown override specifier
error C2059: syntax error: '='
error C2238: unexpected token(s) preceding ';'
fatal error C1903: unable to recover from previous error(s); stopping compilation
编辑。
简化代码:
#include <iostream>
using namespace std;
template <typename T>
class B {
public:
T value;
};
template <typename T>
class A {
public:
B obj;
};
int main() {
B<int> b; // can I simply write B b intead of B<int> b?
b.value = 9;
A<int> a;
a.obj = b;
cout << a.obj.value; // ?
cin.get();
return 0;
}
编译出错:
error C2955: 'B': use of class template requires template argument list
note: see declaration of 'B'
note: see reference to class template instantiation 'A<T>' being compiled
error C2582: 'operator =' function is unavailable in 'B'
warning C4552: '<<': result of expression not used
答案 0 :(得分:0)
即使没有B
也可以编写它:
template<typename T>
struct B {};
template<typename T>
struct A {
void setObj(B<T> obj) {
obj_ = obj; // or obj_ = std::move(obj);
}
B<T> obj_;
};
int main() {
A<int> a;
a.setObj({});
}
除非B
的构造函数被标记为explicit
,否则它将起作用。
要在B<T>
中引用A<T>
,可以引入类型别名:
template<typename T>
struct A {
using B = ::B<T>;
void setObj(B obj) {
obj_ = obj;
}
B obj_;
};
int main() {
using my_A = A<int>;
my_A a;
a.setObj(my_A::B{});
}
编辑后添加。
除非编译器可以通过某种方式推断出模板参数,否则您不能忽略它。在C ++ 17中,我们有template argument deduction,您的代码可以写为:
template<typename T>
struct B {
B(T v) : value(v) {}
T value;
};
template<typename T>
struct A {
A(B<T> o) : obj(o) {}
B<T> obj;
};
int main() {
B b{9};
A a{b};
std::cout << a.obj.value;
}