【问题标题】:Defining template function with std::is_invocable_v outside of class在类外用 std::is_invocable_v 定义模板函数
【发布时间】:2020-12-07 18:41:48
【问题描述】:

我有这门课:

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&amp;&amp; get) 时如何包含typename = std::enable_if_t&lt;std::is_invocable_v&lt;F&gt;&gt; 部分。

首先,我试过了:

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

然后,看了this answer之后,我尝试了:

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

我应该怎么做?

【问题讨论】:

  • 这样做stackoverflow.com/questions/495021/…。间接回答你的问题?
  • 只需在定义中省略默认参数即可。但是您确定要将模板移动到.cpp 文件吗?一般来说,这不是一个好主意。
  • @super 我相信他们会去#include 标题内的.cpp 文件。这对单个 template 类是否有害?
  • @Cem 只是令人困惑。如果您要在头文件中包含定义,将其拆分为.cpp 并包含它只会让阅读代码的人和一些静态分析工具等都想知道发生了什么。我见过有人这样做,但是他们通常将文件命名为.tpp 或其他名称以表明它不是编译单元。

标签: c++ class templates constructor typename


【解决方案1】:
    template <typename F, typename = std::enable_if_t<std::is_invocable_v<F>>>
    Value(F&& get);

这里,std::enable_if_t&lt;std::is_invocable_v&lt;F&gt;&gt; 是一个默认模板参数(第二个模板参数的默认值),并且您已经在类内的声明中指定了它。所以,当你在类外添加一个实现时,你应该省略默认值:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-13
    • 1970-01-01
    • 2020-08-09
    • 1970-01-01
    • 2022-07-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多