[英]Problem on declaring friend function with type traits in a class
I'm playing around with the singleton pattern in C++, and want to implement an global function that completes the construction of a class. 我在 function 中使用了std::is_base_of
,但这使我无法在 class 中声明 function。
这是一个简短的示例:
#include <type_traits>
class A {};
template<typename T>
typename std::enable_if_t<std::is_base_of_v<A, T>, T*>
Instance() { return T(); }
template<typename T>
typename std::enable_if_t<!std::is_base_of_v<A, T>, T*>
Instance() { return T(); }
class B : public A {
protected:
B();
friend B* Instance<B>(); // Error
};
上面的代码在实例化第一个 function 时,使用gcc或使用 MSVC 的 C2139 会导致“不完整类型的无效使用”。
那么,除了将构造函数B::B()
公开之外,还有什么方法可以让我解决它吗?
问题是在 class 的定义过程中,class 仍然不完整,
和std::is_base_of
需要Derived
的完整类型,否则你有 UB。
如果您有权访问 C++17,您可以这样做:
template<typename T>
T* Instance() {
if constexpr (std::is_base_of_v<A, T>) {
return nullptr; // Your impl
} else {
return nullptr; // Your impl
}
}
class B : public A {
protected:
B();
friend B* Instance<B>();
};
您可以使用模板仿函数来构建目标 class 的对象。 这个函子必须是目标 class 的朋友。 请参见下面的示例。
#include <type_traits>
#include <tuple>
class A {};
template <typename T>
struct Instance_t
{
T* operator () () const
{
if constexpr (std::is_base_of_v<A, T>)
{
return new T();
}
else
{
return nullptr;
}
}
};
template <typename T>
constexpr Instance_t<T> Instance{};
class B : public A {
protected:
B()
{}
template <typename T> friend struct Instance_t;
};
int main()
{
auto b=Instance<B>();
std::ignore=b;
return 0;
}
检查演示。
看来我可以只使用 static 成员 function (例如B::Instance()
)来实现 singleton 模式,并使用构造函数来完成特定的功能
代码:
#include <type_traits>
class A {
protected:
A() {
// Do something special here
}
};
class B : public A {
protected:
B();
public:
static B* Instance() {
static B* b = new B();
return b;
}
};
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.