C ++ Cast模板

时间:2016-06-23 06:10:04

标签: 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;
}

此源代码编译良好。现在,我添加了以下类,并且在执行转换的行中有一个编译错误:

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

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

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

5 个答案:

答案 0 :(得分:8)

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

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

由于编译器不知道“强制转换”成员的类型,因此它不允许您使用假定它是类型,模板或两者的操作。为了做到这一点,您需要使用typenametemplate关键字告诉编译器。想象一下,除cast功能模板外,typedef T value_type中还有一个Point<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

答案 1 :(得分:4)

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

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

由于编译器无法知道,它假设第一个,因此你的错误(你无法比较某种类型的东西)。要解决此问题,您需要明确告诉编译器p1.cast是模板化方法:

p2 = p1.template cast<double>();

有关详细信息,请参阅此问题:Where and why do I have to put the "template" and "typename" keywords?

答案 2 :(得分:1)

    p2 = p1.cast<double>();

需要

    p2 = p1.template cast<double>(); 

可以在Where and why do I have to put the "template" and "typename" keywords?找到原因。

答案 3 :(得分:0)

在melpomene后期链接中接受的答案给出了答案。

您需要使用template关键字。

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

答案 4 :(得分:0)

正如其他人所说的那样,你的问题是你需要告诉编译器,依赖模板是模板,并且使用了模板关键字。

 y=x.template cast<Y>();

解决这个问题的方法是让它不再是依赖模板。

最简单的方法是编写一个自由函数

template<class D, class S>
Point<D> cast( Point<S> const& s ){ return s.template cast<D>(); }

现在你可以自由使用:

y = cast<Y>(x);

没有恼人的template关键字,因为cast是模板的事实不再依赖。