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
}
...
};
I get the following error message:
/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>’
From the error message I see that there is a problem with the isPathable part as it doesn't pass on a bool, but I don't understand the why. Where is the problem and how should I change my code? Maybe there is a better solution to such problems?
template<> struct isPathable<char*>
{
static const bool value = true;
};
You're defining a bunch of specializations in this fashion. Your specializations define a boolean member value
, initialized as true
. In your constructor:
/* ... */ std::enable_if_t<isPathable<std::decay_t<Source>> >* = 0)
Note that the template parameter to std::enable_if_t
is a boolean value, but if you parse out what you're specifying here, you're specifying a typename
as a template parameter. You obviously meant something along the line of...
/* ... */ std::enable_if_t<isPathable<std::decay_t<Source>>::value >* = 0)
A few other tweaks you can try and improve your template:
Define your class member as a constexpr
, and not merely a const
.
You can probably avoid using a dummy formal parameter to the constructor, by doing something like:
template <class Source,
std::enable_if_t<isPathable<std::decay_t<Source>>::value >>
path(Source const &source)
{
// do stuff
}