gpt4 book ai didi

c++ - 引入typetraits后非模板的模板定义

转载 作者:行者123 更新时间:2023-11-27 22:40:23 25 4
gpt4 key购买 nike

我有一个 ServiceLocator类(class)。它工作正常,但我想添加一个类型特征,即 ServiceLocator必须使用扩展某些 BaseService 的服务类型类(class)。我的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: error: template definition of non-template ‘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 .

最佳答案

It is working if i remove the typetrait part of my template, so if i remove this part:

这应该是一个关于问题的强烈提示(旁注:这不是类型特征,而是约束)。问题是,你的类模板声明是忽略默认值:

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>);
// ...
};

现在您只有一个模板参数,所以没问题。


请注意,在 C++11 之后,您不再需要 NonCopyable,您可以显式删除特殊成员函数:

struct BaseService {
BaseService() = default;
BaseService(BaseService const&) = delete;
BaseService& operator=(BaseService const&) = delete;
};

关于c++ - 引入typetraits后非模板的模板定义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49492555/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com