在 class 之外使用 std::is_invocable_v 定义模板函数

Defining template function with std::is_invocable_v outside of class

我有这个class:

template <typename T>
class Value {
    private:
    bool fixed;
    union {
        T value;
        std::function<T()> get;
    };

    public:
    Value(const T& value);
    template <typename F, typename = std::enable_if_t<std::is_invocable_v<F>>>
    Value(F&& get);
    Value(const T* pointer);
    ~Value();
    operator T();
};

我最初将其全部写在头文件中,但现在将代码转移到 .cpp 文件中。问题是我不知道如何在定义 Value(F&& get).

时包含 typename = std::enable_if_t<std::is_invocable_v<F>> 部分

首先,我试过:

template <typename T>
template <typename F, typename = std::enable_if_t<std::is_invocable_v<F>>>
Value<T>::Value(F&& get) : fixed(false), get(std::forward<F>(get)) {}

产生了错误:

error: a default template argument cannot be specified on the declaration of a member of a class template outside of its class

然后,在阅读 之后,我尝试了:

template <typename F>
std::enable_if_t<std::is_invocable_v<F>>
Value<T>::Value(F&& get) : fixed(false), get(std::forward<F>(get)) {}

这导致:

error: return type may not be specified on a constructor

我应该怎么做?

    template <typename F, typename = std::enable_if_t<std::is_invocable_v<F>>>
    Value(F&& get);

这里,std::enable_if_t<std::is_invocable_v<F>>是一个默认的模板参数(第二个模板参数的默认值),你已经在class里面的声明中指定了它。所以,当你在 class 之外添加一个实现时,你应该省略默认值:

template <typename T>
template <typename F, typename>
Value<T>::Value(F&& get) : fixed(false), get(std::forward<F>(get)) {}

这确实是错误所说的:a default template argument cannot be specified on the declaration of a member of a class template outside of its class