2014-10-08 58 views
1

我正在使用CRTP来实现一些东西,但在XCode 4.5.2中出现错误。以下代码是仍然复制错误的简化版本。它发生在哪里的方法Api::Enable被定义并有事情做的事实,有没有参数时Api::Enable电话this->T::EnableCRTP error with XCode 4.5.2 - 解析问题,预期表达式

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

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

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

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

When the name of a member template specialization appears after . or -> in a postfix-expression or after a nested-name-specifier in a qualified-id, and the object expression of the postfix-expression is type-dependent or the nested-name-specifier in the qualified-id refers to a dependent type, but the name is not a member of the current instantiation (14.6.2.1), the member template name must be prefixed by the keyword template. Otherwise the name is assumed to name a non-template.

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

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

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