如何在类 A 中传递类型名 T 以在另一个类 B 中使用

How to pass typename T in class A to use in another class B

本文关键字:另一个 类型      更新时间:2023-10-16

我对模板有问题。如何将typename T传递到class A以在class B中使用它?我只想在class A中传递类型名,但我也需要在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

即使没有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,否则这将起作用。


要引用 A<T> 中的B<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<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;
}
相关文章: