【问题标题】:Cannot be explicitly specialized in Visual Studio 2017无法在 Visual Studio 2017 中显式专门化
【发布时间】:2019-04-10 18:06:20
【问题描述】:

我正在使用 cocos2d-x 在 mac 和 windows 上制作可玩的游戏。

我先用Xcode写了代码,可以在mac上运行。

当我将它带到 Windows 并尝试在 Visual Studio 2017 中构建时遇到错误。

NRZNotification.h

#include "cocos2d.h"

class NRZNotification : public cocos2d::Ref
{
protected:
    std::string _name;
    cocos2d::Ref* _sender;

    ...

    cocos2d::ValueMap _valueMap;
    cocos2d::Map<std::string, cocos2d::Ref*> _objectMap;
public:
    const std::string& getName(){return _name;}
    cocos2d::Ref* getSender(){return _sender;}

    NRZNotification();
    virtual ~NRZNotification();
    static NRZNotification* create(const std::string& name, Ref* sender);
    bool init(const std::string& name, Ref* sender);

    ...

    template <typename T,
    typename std::enable_if<!std::is_convertible<T, cocos2d::Ref*>::value,
    std::nullptr_t>::type = nullptr>
    inline T getValue(const std::string& key)
    {
        //CCLOG("%s", __PRETTY_FUNCTION__);
        return 0;
    }
    template <typename T,
    typename std::enable_if<std::is_convertible<T, cocos2d::Ref*>::value,
    std::nullptr_t>::type = nullptr>
    inline T getValue(const std::string& key)
    {
        //CCLOG("%s", __PRETTY_FUNCTION__);
        return dynamic_cast<T>(_objectMap.at(key));
    }
};
#include "NRZNotification_Private.h"

NRZNotification_Private.h

#include "NRZNotification.h"

...

#pragma mark - get value

template <>
inline int NRZNotification::getValue<int,nullptr>(const std::string& key)
{
    if (_valueMap.find(key) == _valueMap.end()) {
        return 0;
    } else {
        return _valueMap.at(key).asInt();
    }
}
template <>
inline float NRZNotification::getValue(const std::string& key)
{
    if (_valueMap.find(key) == _valueMap.end()) {
        return 0.0f;
    } else {
        return _valueMap.at(key).asFloat();
    }
}
template <>
inline double NRZNotification::getValue(const std::string& key)
{
    if (_valueMap.find(key) == _valueMap.end()) {
        return 0.0;
    } else {
        return _valueMap.at(key).asDouble();
    }
}

...

这些代码在 mac 上运行成功,但在 Visual Studio 2017 中,调用 getValue() 会出现“无法显式专门化”的错误。

getValue()是一个函数模板,根据返回值是否是cocos2d::Ref的子类来划分实现。

此外,对 int、float、string 等进行了专门化。

我应该如何修复这个代码?

我使用的是 cocos2d-x 3.17.1。

谢谢。

【问题讨论】:

  • 显示编译错误。

标签: c++ visual-studio cocos2d-x sfinae


【解决方案1】:

我冒昧地根据您的代码创建了一个 MCVE。

#include <type_traits>

struct A {
    template<typename T, typename std::enable_if<!std::is_convertible<T, A>::value, int>::type = 0>
    T getValue() {
        return 1;
    }
    template<typename T, typename std::enable_if<std::is_convertible<T, A>::value, int>::type = 0>
    T getValue() {
        return T();
    }
};

template<>
inline int A::getValue<int, 0>() {
    return 3;
}

int main() {
    A a;
    return a.getValue<int>();
}

确实,MSVC 2019 编译失败

<source>(15): error C2910: 'A::getValue': cannot be explicitly specialized

而 GCC 和 clang 编译它就好了。 Live demo.

幸运的是,解决方案很简单 - 只需删除显式模板参数即可。无论如何它们都是多余的:

template<>
inline int A::getValue() {
    return 3;
}

所以对于你的情况,从

中删除&lt;int,nullptr&gt;
template <>
inline int NRZNotification::getValue<int,nullptr>(const std::string& key)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-15
    相关资源
    最近更新 更多