C++ 用std::is\u invocable\u v定义模板函数在类之外

C++ 用std::is\u invocable\u v定义模板函数在类之外,c++,class,templates,constructor,typename,C++,Class,Templates,Constructor,Typename,我有这门课: 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

我有这门课:

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();
};
产生错误的原因:

error: a default template argument cannot be specified on the declaration of a member of a class template outside of its class
然后,在阅读之后,我试着:

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)) {}
template <typename F>
std::enable_if_t<std::is_invocable_v<F>>
Value<T>::Value(F&& get) : fixed(false), get(std::forward<F>(get)) {}
我应该怎么做呢?

模板
值(F&get);
这里,
std::enable_,如果\u t
是默认模板参数(第二个模板参数的默认值),并且您已经在类内的声明中指定了它。因此,在类外添加实现时,应忽略默认值:

template <typename T>
template <typename F, typename>
Value<T>::Value(F&& get) : fixed(false), get(std::forward<F>(get)) {}
模板
模板
Value::Value(F&&get):修复(false),获取(std::forward(get)){}

这确实是错误所说的:
不能在类模板成员的声明中指定其类之外的默认模板参数

执行此操作。间接回答你的问题?只需在定义中省略默认参数。但是否确实要将模板移动到
.cpp
文件?一般来说,这不是一个好主意。@super我相信他们会在标题中包含
.cpp
文件。这对单个
模板
类是否有害?@Cem只是让人困惑。如果要在头文件中包含定义,将其拆分为
.cpp
,并包含它只会使阅读代码和一些静态分析工具等的人都想知道发生了什么。我见过有人这样做,但他们通常会将文件命名为
.tpp
或其他东西,以表明它不是编译单元。
template <typename T>
template <typename F, typename>
Value<T>::Value(F&& get) : fixed(false), get(std::forward<F>(get)) {}