You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

模板类初始化赋值报conversion to non-scalar type错误的解决方法

模板类跨类型初始化赋值错误的解决方案

问题描述

执行TemplateTest<int> t3 = t2;(其中t2为TemplateTest<double>类型)进行初始化时触发conversion to non-scalar type错误,但先声明TemplateTest<int> t3;再执行t3 = t2;的赋值操作却能正常运行。

完整代码

#include <iostream>
using namespace std;

template <typename T> class TemplateTest {
    private:
        T m_data;
    public:
        TemplateTest();
        TemplateTest(const T inputData);
        T GetData() const;
        template<class U> TemplateTest<T>& operator= (const TemplateTest<U> &rhs);
        void Print();
};

template <class T>
TemplateTest<T>::TemplateTest()
{
    m_data = 0;
}

template <class T>
TemplateTest<T>::TemplateTest(const T inputData)
{
    m_data = inputData;
}

template <class T>
void TemplateTest<T>::Print()
{
    std::cout<<m_data<<std::endl;
}

template <class T>
T TemplateTest<T>::GetData() const
{
    return m_data;
}

template<class T> template<class U>
TemplateTest<T>& TemplateTest<T>::operator= (const TemplateTest<U> &rhs)
{
    m_data = rhs.GetData();
    return *this;
}

int main()
{
    TemplateTest<int> t1(12);
    TemplateTest<double> t2(1.2);
    TemplateTest<int>t3 = t2;
    t3.Print();
    return 0;
}

原因分析

  • TemplateTest<int> t3 = t2;属于拷贝初始化,编译器需要将TemplateTest<double>转换为TemplateTest<int>,这依赖于类中存在可以接受TemplateTest<U>类型参数的转换构造函数。
  • t3 = t2;属于赋值操作,调用的是你已经显式定义的模板版operator=,因此可以正常执行。

你的类仅提供了接受T类型的构造函数,没有定义支持跨模板实例转换的构造函数,导致拷贝初始化失败。

解决方案

给模板类添加一个模板版的转换构造函数:

1. 更新类声明

在TemplateTest类的public区域添加构造函数声明:

template<class U> TemplateTest(const TemplateTest<U>& rhs);

修改后的类声明:

template <typename T> class TemplateTest {
    private:
        T m_data;
    public:
        TemplateTest();
        TemplateTest(const T inputData);
        // 新增跨类型转换构造函数
        template<class U> TemplateTest(const TemplateTest<U>& rhs);
        T GetData() const;
        template<class U> TemplateTest<T>& operator= (const TemplateTest<U> &rhs);
        void Print();
};

2. 实现转换构造函数

在类外添加模板构造函数的实现:

template<class T> template<class U>
TemplateTest<T>::TemplateTest(const TemplateTest<U>& rhs) {
    m_data = rhs.GetData();
}

修改后的完整代码

#include <iostream>
using namespace std;

template <typename T> class TemplateTest {
    private:
        T m_data;
    public:
        TemplateTest();
        TemplateTest(const T inputData);
        template<class U> TemplateTest(const TemplateTest<U>& rhs);
        T GetData() const;
        template<class U> TemplateTest<T>& operator= (const TemplateTest<U> &rhs);
        void Print();
};

template <class T>
TemplateTest<T>::TemplateTest()
{
    m_data = 0;
}

template <class T>
TemplateTest<T>::TemplateTest(const T inputData)
{
    m_data = inputData;
}

template<class T> template<class U>
TemplateTest<T>::TemplateTest(const TemplateTest<U>& rhs) {
    m_data = rhs.GetData();
}

template <class T>
void TemplateTest<T>::Print()
{
    std::cout<<m_data<<std::endl;
}

template <class T>
T TemplateTest<T>::GetData() const
{
    return m_data;
}

template<class T> template<class U>
TemplateTest<T>& TemplateTest<T>::operator= (const TemplateTest<U> &rhs)
{
    m_data = rhs.GetData();
    return *this;
}

int main()
{
    TemplateTest<int> t1(12);
    TemplateTest<double> t2(1.2);
    TemplateTest<int> t3 = t2;
    t3.Print();
    return 0;
}

补充说明

  • 拷贝初始化过程中,编译器优先匹配拷贝/转换构造函数,而非赋值运算符
  • 模板类不会自动生成跨实例类型的转换构造函数,必须显式定义才能支持此类操作

内容的提问来源于stack exchange,提问作者Renu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 20:52:08