[英]Template definition of non-template after introducing typetraits
我有一个ServiceLocator
类。 它工作正常,但是我想添加一个类型特征,即ServiceLocator
必须使用扩展了某些BaseService
类的Service-Type。 我的BaseService
类具有一些我希望每个服务都具有的属性,例如不可复制。 因此,让我们看一下我的代码:
#pragma once
#include <memory>
#include <type_traits>
#include "BaseService.hpp"
template <typename T, typename std::enable_if<std::is_base_of<BaseService, T>::value>::type* = nullptr>
class ServiceLocator {
private:
ServiceLocator() {}
static std::unique_ptr<T> service;
public:
static void provide(std::unique_ptr<T> service) {
ServiceLocator::service = std::move<>(service);
}
static T &getService() {
return *(ServiceLocator::service.get());
}
};
template <typename T>
std::unique_ptr<T> ServiceLocator<T>::service;
这段代码并不是那么神奇。 但是我收到以下错误:
ServiceLocator.hpp:22:39:错误:非模板'std :: unique_ptr <_Tp> ServiceLocator :: service'的模板定义std :: unique_ptr ServiceLocator :: service;
就像我说的那样,我的BaseService
类不是特别的,但是出于完整性考虑:
#pragma once
#include "NonCopyable.hpp"
class BaseService : private NonCopyable {
};
不可复制:
#pragma once
class NonCopyable {
public:
NonCopyable() {}
private:
NonCopyable(const NonCopyable&) = delete;
NonCopyable& operator=(const NonCopyable&) = delete;
};
如果我删除模板的类型特征部分,那么它是有效的,所以如果我删除此部分:
, typename std::enable_if<std::is_base_of<BaseService, T>::value>::type* = nullptr
我试图制作固定类型的unique_ptr
: std::unique_ptr<BaseClass>
并在我的两个方法中使用static_cast
。 但是无法使它正常工作。 唯一需要的是类型T
必须扩展我的BaseService
。
如果我删除模板的typetrait部分,则可以正常工作,因此,如果我删除此部分:
这本来应该是关于出了什么问题的强烈暗示(旁注:这不是类型特征,而是约束)。 问题是,您正在使用类模板声明,而忽略默认值:
template <typename T, typename std::enable_if<std::is_base_of<BaseService, T>::value>::type*>
class ServiceLocator { ... };
也就是说,它需要两个模板参数:一种类型,一种非类型。 您的类外静态定义为:
template <typename T>
std::unique_ptr<T> ServiceLocator<T>::service;
那是一个模板参数。 那不是什么。 您不能在此依赖默认值,因为还需要为非默认情况定义静态成员。
这里的解决方案只是将约束移到主体中-因为作为模板参数,我认为它不能为您解决任何问题:
template <typename T>
class ServiceLocator {
static_assert(std::is_base_of_v<BaseService, T>);
// ...
};
现在,您只有一个template参数,因此没有问题。
请注意,在C ++ 11之后,您不再需要NonCopyable
,只需显式删除特殊成员函数即可:
struct BaseService {
BaseService() = default;
BaseService(BaseService const&) = delete;
BaseService& operator=(BaseService const&) = delete;
};
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.