【问题标题】:c++ class constructor template with std::enable_if and std::decayc++ 类构造函数模板,带有 std::enable_if 和 std::decay
【发布时间】:2018-04-03 00:49:57
【问题描述】:
class DirectoryEntry; // forward declaration

template <class T>
struct isPathable { static const bool value = false; };

template<> struct isPathable<char*>
{
    static const bool value = true;
};
template<> struct isPathable<const char*>
{
    static const bool value = true;
};
template<> struct isPathable<std::string>
{
    static const bool value = true;
};
template<> struct isPathable<std::vector<char> >
{
    static const bool value = true;
};
template<> struct isPathable<std::list<char> >
{
    static const bool value = true;
};
template<> struct isPathable<DirectoryEntry>
{
    static const bool value = true;
};

class path
{
private:
    std::string m_pathname;
public:

    // constructors:
    // ------------------------
    path() noexcept {}
    path(const path &p) : m_pathname(p.m_pathname) {}

    template <class Source>
    path(Source const &source,
        std::enable_if_t<isPathable<std::decay_t<Source>> >* = 0)
    {
        // do stuff
    }
...
};

我收到以下错误消息:

/usr/bin/c++   -I../lib -Wall -Werror -std=c++17 -g   -pthread -MD -MT app/CMakeFiles/infinityApp.dir/src/main.cpp.o -MF app/CMakeFiles/infinityApp.dir/src/main.cpp.o.d -o app/CMakeFiles/infinityApp.dir/src/main.cpp.o -c ../app/src/main.cpp

error: type/value mismatch at argument 1 in template parameter list for ‘template<bool _Cond, class _Tp> using enable_if_t = typename std::enable_if::type’

std::enable_if_t<isPathable<std::decay_t<Source>> >* = 0)
                                                  ^
note:   expected a constant of type ‘bool’, got ‘isPathable<typename std::decay<_Tp>::type>’

从错误消息中,我看到 isPathable 部分存在问题,因为它没有传递布尔值,但我不明白原因。问题出在哪里,我应该如何更改我的代码?也许有更好的解决方案来解决这些问题?

【问题讨论】:

  • 你不是说...std::enable_if_t&lt;isPathable&lt;std::decay_t&lt;Source&gt;&gt;::value&gt; ?
  • 是的。谢谢!但是,我似乎不能接受 cmets 作为正确答案?
  • 正确,我会稍微正式一点。

标签: c++ constructor std enable-if


【解决方案1】:
template<> struct isPathable<char*>
{
    static const bool value = true;
};

您正在以这种方式定义一堆专业。你的特化定义了一个布尔成员value,初始化为true。在您的构造函数中:

/* ... */ std::enable_if_t<isPathable<std::decay_t<Source>> >* = 0)

请注意,std::enable_if_t 的模板参数是一个布尔值,但如果您解析出您在此处指定的内容,您将指定 typename 作为模板参数。显然你的意思是……

/* ... */ std::enable_if_t<isPathable<std::decay_t<Source>>::value >* = 0)

您可以尝试其他一些调整来改进您的模板:

  • 将您的班级成员定义为constexpr,而不仅仅是const

  • 您可以通过执行以下操作来避免在构造函数中使用虚拟形式参数:

    template <class Source,
          std::enable_if_t<isPathable<std::decay_t<Source>>::value >>
    path(Source const &source)
    {
        // do stuff
    }
    

【讨论】:

  • 使用您最新的“避免使用虚拟形式参数”提示,您缺少 ::value。只为未来的读者。否则好主意。谢谢!
猜你喜欢
  • 2019-10-04
  • 2022-11-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-03-31
相关资源
最近更新 更多