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

时间:2019-11-23 11:23:33

标签: c++ templates

我对模板有疑问。如何将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

1 个答案:

答案 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;
}