[英]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. I'm playing around with the singleton pattern in C++, and want to implement an global function that completes the construction of a class. I used
std::is_base_of
in that function, but that makes it impossible for me to declaring the function in the class.我在 function 中使用了
std::is_base_of
,但这使我无法在 class 中声明 function。
Here's a short example:这是一个简短的示例:
#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
};
The above code will cause "invalid use of incomplete type" using gcc or C2139 using MSVC when instantiating the first function.上面的代码在实例化第一个 function 时,使用gcc或使用 MSVC 的 C2139 会导致“不完整类型的无效使用”。
So, other than making constructor B::B()
to be public, is there any possible way for me to work around with it?那么,除了将构造函数
B::B()
公开之外,还有什么方法可以让我解决它吗?
Issue is that during definition of class, the class is still incomplete ,问题是在 class 的定义过程中,class 仍然不完整,
and std::is_base_of
required complete type for Derived
, else you have UB.和
std::is_base_of
需要Derived
的完整类型,否则你有 UB。
If you have access to C++17, you might do:如果您有权访问 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>();
};
You can use a template functor to build objects of the target class.您可以使用模板仿函数来构建目标 class 的对象。 This functor must be a friend of the target class.
这个函子必须是目标 class 的朋友。 See example below.
请参见下面的示例。
#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;
}
Seems that I can just use static member function (eg B::Instance()
) to achieve singleton pattern, and use constructor to finish the specific functions...看来我可以只使用 static 成员 function (例如
B::Instance()
)来实现 singleton 模式,并使用构造函数来完成特定的功能
Code:代码:
#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.