不能明确专攻 Visual Studio 2017
Cannot be explicitly specialized in Visual Studio 2017
我正在制作一款可在 mac 和 windows 上使用 cocos2d-x 玩的游戏。
我先把代码写在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() 时出现错误 "cannot be explicitly specialized"。
getValue()是一个函数模板,根据return值是否是cocos2d::Ref的子类来划分实现。
此外,还对int、float、string等进行了特化
我应该如何修复此代码?
我正在使用 cocos2d-x 3.17.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;
}
所以对于你的情况,从
中删除<int,nullptr>
template <>
inline int NRZNotification::getValue<int,nullptr>(const std::string& key)
我正在制作一款可在 mac 和 windows 上使用 cocos2d-x 玩的游戏。
我先把代码写在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() 时出现错误 "cannot be explicitly specialized"。
getValue()是一个函数模板,根据return值是否是cocos2d::Ref的子类来划分实现。
此外,还对int、float、string等进行了特化
我应该如何修复此代码?
我正在使用 cocos2d-x 3.17.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;
}
所以对于你的情况,从
中删除<int,nullptr>
template <>
inline int NRZNotification::getValue<int,nullptr>(const std::string& key)