带有 std::enable_if 和 std::decay 的 c++ class 构造函数模板
c++ class constructor template with std::enable_if and 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,但我不明白为什么。问题出在哪里,我应该如何更改我的代码?也许有更好的解决此类问题的方法?
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)
您可以尝试进行一些其他调整并改进您的模板:
将您的 class 成员定义为 constexpr
,而不仅仅是 const
。
您可以避免使用构造函数的虚拟形式参数,方法如下:
template <class Source,
std::enable_if_t<isPathable<std::decay_t<Source>>::value >>
path(Source const &source)
{
// do stuff
}
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,但我不明白为什么。问题出在哪里,我应该如何更改我的代码?也许有更好的解决此类问题的方法?
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)
您可以尝试进行一些其他调整并改进您的模板:
将您的 class 成员定义为
constexpr
,而不仅仅是const
。您可以避免使用构造函数的虚拟形式参数,方法如下:
template <class Source, std::enable_if_t<isPathable<std::decay_t<Source>>::value >> path(Source const &source) { // do stuff }