首页 > 解决方案 > 在类中声明具有类型特征的友元函数的问题

问题描述

我正在玩 C++ 中的单例模式,并希望实现一个完成类构建的全局函数。我std::is_base_of在该函数中使用过,但这使我无法在类中声明该函数。

这是一个简短的示例:

#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
};

上面的代码在实例化第一个函数时使用 gcc 或C2139使用 MSVC会导致“不完整类型的无效使用” 。

那么,除了让构造函数B::B()公开之外,我还有什么办法可以解决它吗?

标签: c++declarationfriendtypetraits

解决方案


问题是在定义类期间,类仍然不完整

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>();
};

演示


推荐阅读