XCode 4.5.2的CRTP错误 - 解析问题,预期表达式

时间:2014-10-08 20:14:15

标签: c++ xcode templates clang xcode4.5

我正在使用CRTP来实现某些功能,但我在XCode 4.5.2中遇到了错误。以下代码是仍然复制错误的简化版本。它出现在定义方法Api::Enable的行上,并且与Api::Enable调用this->T::Enable

时没有参数的事实有关
enum Enum
{
    FOO,
    BAR,
    BAZ,
};

template <typename T>
class Api
{
public:
    template <Enum E, bool On> void Enable() {static_cast<T *>(this)->Enable<E, On>();}
};

class ApiImpl : public Api<ApiImpl>
{
public:
    template <Enum E, bool On> void Enable() {}
};

int main(int argc, const char * argv[])
{
    ApiImpl clsApi;
    clsApi.Enable<FOO, true>();
    return 0;
}

以下是Xcode中错误的屏幕截图:http://i.imgur.com/IxEOgQ6.png。无论我使用“Apple LLVM编译器4.1”还是“LLVM GCC 4.2”,我都会得到同样的错误。 MSVC Express 2010编译时没有错误。

请注意,添加函数参数会导致错误消失。以下编译正常:

enum Enum
{
    FOO,
    BAR,
    BAZ,
};

template <typename T>
class Api
{
public:
    template <Enum E , bool On> void Enable(unsigned int X) {static_cast<T *>(this)->Enable<E, On>(X);}
};

class ApiImpl : public Api<ApiImpl>
{
public:
    template <Enum E, bool On> void Enable(unsigned int) {}
};

int main(int argc, const char * argv[])
{
    ApiImpl clsApi;
    clsApi.Enable<FOO, true>(0);
    return 0;
}

1 个答案:

答案 0 :(得分:1)

您应该使用template关键字来解析依赖模板名称:

template <Enum E, bool On> void Enable() {
    static_cast<T*>(this)->template Enable<E, On>();
}

C ++ 11,[temp.names]/4

  

当成员模板专业化的名称出现之后。或 - &gt;在后缀表达式中或之后   qualified-id中的nested-name-specifier,postfix-expression的对象表达式依赖于类型   或者qualified-id中的nested-name-specifier引用依赖类型,但名称不是其成员   在当前实例化(14.6.2.1)中,成员模板名称必须以关键字模板为前缀。   否则,假定该名称命名非模板。

如果Enable()例如template <typename T> void Enable(){},则clang会显示错误:error: use 'template' keyword to treat 'Enable' as a dependent template name

我不知道为什么它会在你的情况下产生那些不相关的消息(当模板参数不是类型时)。我认为这可以作为错误报告发布。 (我在clang 3.6上测试过 - 相同)。

此外,gcc 4.8和4.9不会对此代码产生任何错误,我相信也是错误的。