繁体   English   中英

在 class 中声明具有类型特征的朋友 function 时出现问题

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM