我想做一些类似的事情
template <typename T>
class TemporalAlarmDelay<T, std::enable_if<std::is_base_of<std::chrono::duration< , >, T>::value, T>::type>
{
public:
explicit TemporalAlarmDelay(T delay)
: mDelay(delay)
{
}
private:
T mDelay;
std::chrono::steady_clock::time_point mTriggerTime;
};
int main(int argc, char** args)
{
TemporalAlarmDelay<std::chrono::nanoseconds> nanosecondDelay; // this should work
TemporalAlarmDelay<std::chrono::milliseconds> millisecondDelay; // this should work
TemporalAlarmDelay<std::chrono::seconds> secondDelay; // this should work
TemporalAlarmDelay<int> failDelay; // fail to instantiate
}
其目的是限制std::chrono::duration
的类型(例如std::chrono::milliseconds
、std::chrono::seconds
)。对此,最好的方法是什么?根据我的例子,我认为我可以使用std::is_base_of
,但我现在意识到辅助类型(例如std::chrono::milliseconds
、std::chrono::seconds
等)不使用继承-derrr,这是一个多么愚蠢的想法。
对于问题的最简单解决方案。。。
#include <chrono>
class TemporalAlarmDelay
{
public:
explicit TemporalAlarmDelay(std::chrono::steady_clock::duration delay)
: mDelay(delay)
{
}
private:
std::chrono::steady_clock::duration mDelay;
std::chrono::steady_clock::time_point mTriggerTime;
};
int main()
{
using namespace std::chrono_literals;
TemporalAlarmDelay nanosecondDelay{1ns}; // this works
TemporalAlarmDelay millisecondDelay{1ms}; // this works
TemporalAlarmDelay secondDelay{1s}; // this works
TemporalAlarmDelay failDelay{1}; // compile-time error
}
您可以使用模板专业化:
template <typename T>
class TemporalAlarmDelay
{
~TemporalAlarmDelay() = delete; // prevent instantiation
};
template <typename R, typename P>
class TemporalAlarmDelay<std::chrono::duration<R, P>>
{
// your code
};
@Jarod42建议你甚至可以逃脱:
template <typename> class TemporalAlarmDelay;
而不是上面的前四行。
您可以创建特征:
template <typename T> struct is_chrono_duration : std::false_type {};
template <typename R, typename P>
struct is_chrono_duration<std::chrono::duration<R, P>> : std::true_type {};
然后:
template <typename T>
class TemporalAlarmDelay
{
static_assert(is_chrono_duration<T>::value, "!");
// your code
};
从Jarod42的is_chrono_duration
(好吧……老实说,复制它)中获得灵感,这是一种可能的基于SFINAE的(超过默认布尔值)解决方案
template <typename T, bool = is_chrono_duration<T>::value>
class TmpAlrD;
template <typename T>
class TmpAlrD<T, true>
{
// ...
};
以下是的完整编译示例
#include <chrono>
#include <type_traits>
template <typename>
struct is_chrono_duration : std::false_type
{ };
template <typename R, typename P>
struct is_chrono_duration<std::chrono::duration<R, P>> : std::true_type
{ };
template <typename T, bool = is_chrono_duration<T>::value>
class TmpAlrD;
template <typename T>
class TmpAlrD<T, true>
{
public:
explicit TmpAlrD(T delay = T{}) : mDelay(delay)
{ }
private:
T mDelay;
std::chrono::steady_clock::time_point mTriggerTime;
};
int main ()
{
TmpAlrD<std::chrono::nanoseconds> nsDelay; // compile
TmpAlrD<std::chrono::milliseconds> msDelay; // compile
TmpAlrD<std::chrono::seconds> sDelay; // compile
//TemporalAlarmDelay<int> // compilation error
}