模板类的 C++ 转换

标签 c++ templates gcc casting

我有一个关于模板的问题。我想要一个模板化类,其中包含一个 float 或 double 数组。

我可以编写一个复制它的 clone() 函数。没问题。但是,我想要另一个名为 cast() 的函数,它在 double 和 float 之间来回转换。之前已经对此进行了一些讨论,但我认为问题不一样:

stackoverflow.com/questions/714213/c-template-casting

我遇到的问题是编译器错误,而不是链接器错误。错误信息是:

main.cpp: In function `void caster()':
main.cpp:63: error: expected primary-expression before "double"
main.cpp:63: error: expected `;' before "double"
main.cpp:64: error: expected primary-expression before "float"
main.cpp:64: error: expected `;' before "float"
main.cpp:65: error: expected primary-expression before '>' token
main.cpp:65: error: expected primary-expression before ')' token

我转储了下面的代码。第 63、64 和 65 行是我用“此处错误”注释的地方。

顺便说一下,我的编译器是“GNU C++ version 3.4.5 20051201 (Red Hat 3.4.5-2) (x86_64-redhat-linux) compiled by GNU C version 3.4.5 20051201 (Red Hat 3.4.5- 2)".

经过一番谷歌搜索,发现有人已经遇到过这个问题:

gcc.gnu.org/ml/gcc-help/2006-04/msg00022.html

这里有一个解决方案:

gcc.gnu.org/ml/gcc-help/2006-04/msg00023.html

但是当发帖人问到为什么有效时,答案不是很清楚:

gcc.gnu.org/ml/gcc-help/2006-04/msg00025.html

不幸的是,链接已失效,而且我没有 Stroustrup 的第三版。现在,我有我的修复,我的代码可以工作。但是,Stackoverflow,为什么它有效?


#include <stdio.h>

// =================== This would be the header ===================
template <class T>
class foo
{
public:
             foo(const T val) {d_data = new double; *d_data = val;}
    virtual ~foo() {delete d_data;};

    foo* clone() const;

    template<class U>
    foo<U>* cast() const;

private:
    double *d_data;
};

// =================== This would be the implementation of the class ===================
template<class T>
foo<T>* foo<T>::clone() const
{
    return new foo<T>(*d_data);
}

template<class T>
template<class U>
foo<U>* foo<T>::cast() const
{
    return new foo<U>(*d_data);
}

template class foo<float>;
template class foo<double>;

template foo<float>* foo<float>::cast() const;
template foo<float>* foo<double>::cast() const;
template foo<double>* foo<float>::cast() const;
template foo<double>* foo<double>::cast() const;

// =================== Using the class ===================
template <class T>
void caster()
{
    foo<double> *f1 = NULL;
    foo<float>  *f2 = NULL;
    foo<T>      *f3 = NULL;

    // I am looking at something that compiles
    // I don't care about linking for now
    // This will crash at runtime because of
    // NULL, but that's just an example

    f1->cast<double>(); // compiler OK
    f1->cast<float>();  // compiler OK
    f1->cast<T>();      // compiler OK

    f2->cast<double>(); // compiler OK
    f2->cast<float>();  // compiler OK
    f2->cast<T>();      // compiler OK

    f3->cast<double>(); // Error here
    f3->cast<float>();  // Error here
    f3->cast<T>();      // Error here

    f3->foo<T>::template cast<double>(); // It works!
    f3->foo<T>::template cast<float>();  // It works!
    f3->foo<T>::template cast<T>();      // It works!
}

int main(int argc, char **argv)
{
    return 0;
}

最佳答案

f3->cast<double>(); // Error here 

在这一行中,编译器不知道 < 是否存在。在 f3->cast 之后应该表示模板参数的开始或者它是否是一个小于比较运算符。

明确指定它代表模板参数的开始。正确的做法是

f3->template cast<double>();

总而言之,.template符号(和类似的符号,如 ->template )应该只在模板内部使用,并且只有当它们遵循依赖于模板参数的东西时(例如表达式 f3 取决于模板参数 T )

关于模板类的 C++ 转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4056766/

相关文章:

c++ - QQmlEngine 和 cmake

c++ - C++ 中的内置类型 bool 或 C 中的 stdbool.h 类型将 TRUE 和 FALSE 定义为不是机器字的大小?

c++ - 无法在 mac 上构建 google protocol buffers 教程

C++模板类冒泡排序操作数错误

c - gcc:错误:/e:/源代码/C/Practice/helloWorld.c:参数无效

c++ - 如何捕获范围错误的 out_of_range 异常( vector 差一错误)

java - Apache 瓷砖 : how to access definition name

c++ - 在定义中使用 typedef 类型

c++ - 枚举类的基础类型别名为整数类型(编译错误)

c++ - Eclipse-PDT:更改包含文件夹