模板类实例之间的类型转换

kan*_*nra 1 c++ templates casting type-conversion

我目前正在尝试使用c ++样式类型转换。为此,我创建了一个模板类pClass,它接受一些T类型的元素并将其打印出来。

现在,我想(例如)将type的实例转换pClass<char>pClass<int>。但是,非我的类型转换尝试似乎按预期方式工作。

我已经发现它dynamic_cast用于在运行时以及处理虚拟函数/多态类时进行转换,在此情况并非如此。static_cast用于在编译时进行转换。那么,对于我来说,static_cast应该是正确的选择吗?

这里有关stackoverflow的一些主题也有类似的问题,但是仅当处理多个类并在它们之间进行继承时才有类似的问题。不幸的是,我无法真正将它们与我的问题联系起来(例如,模板调用之间的C ++ Casting)。

#include <iostream>

template <typename T>
class pClass {
    public:
    T value;
    pClass(T value) {
        this->value = value;
        std::cout << value << std::endl;
    }
    virtual ~pClass() {}
};

int main() {
    pClass<int> pInt(5);
    pClass<char> pChar('a');
    pClass<float> pFloat(4.2f);

    // pClass<int> pInt2 = static_cast<pClass<int>&>(pChar); //  gives invalid type conversation
    // pClass<int>& pInt3 = dynamic_cast<pClass<int>&>(pChar); // warning: dynamic_cast of ‘pClass<char> pChar’ to ‘class pClass<int>&’ can never succeed
    // pClass<int> pInt4 = reinterpret_cast<pClass<int>&>(pChar); // works, but does not print anything
    // std::cout << pInt2.value << std::endl; // prints 3277 or even 327777 exept of 97, which is the expected ASCII representation
}
Run Code Online (Sandbox Code Playgroud)

对于每次强制转换尝试,我都会在命令后面写入错误消息/输出结果。我很感谢有任何提示可以帮助我在这里找到正确的类型。

非常感谢你!

Qui*_*mby 5

尽管类型来自同一模板,但它们是完全不相关的。您不能只在它们之间进行强制转换,编译器如何才能知道强制转换的含义?由于模板的原因,专门化pClass<char>甚至可能不包含char可转换为的int

解决的办法是写铸造的含义使用转换操作符:

template <typename T>
class pClass {
    public:
    T value;
    pClass(T value) {
        this->value = value;
        std::cout << value << std::endl;
    }
    virtual ~pClass() {}

    template<typename U>
    operator pClass<U>(){
        return pClass<U>(static_cast<U>(this->value));
    }
};
Run Code Online (Sandbox Code Playgroud)

上述方法允许任何两个之间浇铸pClass<T>pClass<U>通过铸造所存储的值的值。这将使以下代码编译:

pClass<int> pInt{1};
pClass<float> pfloat{pInt};
Run Code Online (Sandbox Code Playgroud)

第二行是复制构造函数pClass<float>::pClass<float>(const pClass<float>&);,它使用隐式强制转换将其转换pIntpClass<float>类型。

我建议使转换运算符明确:

template<typename U> explicit operator pClass<U>()
Run Code Online (Sandbox Code Playgroud)

这将禁止上面的隐式转换,但仍允许显式转换:

pClass<float> pfloat{static_cast<pClass<float>>(pInt)};
Run Code Online (Sandbox Code Playgroud)

  • 关于术语的一点:这不是**强制转换运算符**;它是一个**转换运算符**。强制转换是您在源代码中编写的内容,用于告诉编译器进行转换。该运算符可以应用于不使用强制转换的情况。+1。 (3认同)