шаблон конструктора класса c ++ с использованием std :: enable_if и std :: decay

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, так как она не передается как bool, но я не понимаю, почему. Где проблема и как мне изменить мой код? Может быть, есть лучшее решение таких проблем?

0

Решение

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
    }
    
0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]