C++ Cast模板

Sae*_*nen 4 c++ templates

我有这个源代码,允许我投射Point<float>Point<double>:

template<class T> struct Point{
    template <typename NewType> Point<NewType> cast() const{
        return Point<NewType>();
    }       
};

int main(){
    Point<float> p1;
    Point<double> p2;
    p2 = p1.cast<double>();

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

这个源代码编译得很好.现在,我添加以下类,我在执行转换的行中有一个编译错误:

template <class T> struct PointContainer{
    void test(){
        Point<T> p1;
        Point<double> p2;
        p2 = p1.cast<double>(); //compilation error
    }
};
Run Code Online (Sandbox Code Playgroud)

编译错误:error: expected primary-expression before ‘double’.

为什么我会收到此错误,如何解决?

Jav*_*tín 8

简短回答:您需要template在提供错误的行中的成员访问运算符(点)之后添加关键字.

答案很长:在PointContainer<T>,T是一个未知的模板变量.由于在C++模板中可以具有允许与基本模板完全不同的特化,因此Point<T>在将T替换为实际类型之前,编译器不知道类型是否具有作为函数模板的成员强制转换.这就是为什么你可以在main中使用强制转换:Point<float>是一种具体的类型,编译器知道它确实有那个函数模板.

由于编译器不知道"强制转换"成员的类型,因此它不允许您使用假定它是类型,模板或两者的操作.为了做到这一点,你需要使用typenametemplate关键字告诉编译器.试想一下,除了你的cast函数模板存在typedef T value_typePoint<T>:

Point<float>::value_type f = 1.0f; // OK
Point<T>::value_type f = 1.0f; // Bad, compiler does not identify that as a type
typename Point<T>::value_type f = 1.0f; // OK

Point<float> pf;
Point<T> pT;
Point<double> pd1 = pf.cast<double>(); // OK
Point<double> pd2 = pT.cast<double>(); // Bad, compiler does not know cast is a template
Point<double> pd3 = pT.template cast<double>(); // OK
Run Code Online (Sandbox Code Playgroud)


Hol*_*olt 5

Point<T>是一个依赖名称(它取决于模板参数T),所以编译器并不真正知道是什么Point<T>::cast

  • Point<T>::cast可能是一个属性,然后p1.cast <将被视为与接下来的比较。
  • Point<T>::cast 可能是一个模板(你的情况)。

由于编译器不知道,它假定第一个,因此您的错误(您无法将某些内容与类型进行比较)。要解决这个问题,您需要明确告诉编译器这p1.cast是一个模板化方法:

p2 = p1.template cast<double>();
Run Code Online (Sandbox Code Playgroud)

有关更多信息,请参阅此问题:我必须将“模板”和“类型名称”关键字放在哪里以及为什么要放?


Sto*_*ica 0

链接的 Melpomene 帖子中接受的答案为您提供了答案。

您需要使用template关键字。

template <class T> struct PointContainer{
    void test(){
        Point<T> p1;
        Point<double> p2;
        p2 = p1.template cast<double>(); 
    }
};
Run Code Online (Sandbox Code Playgroud)