[英]Specializing a template method with enable_if
我正在編寫一個存儲std::function
的模板類,以便稍后調用它。 這是簡化的代碼:
template <typename T>
struct Test
{
void call(T type)
{
function(type);
}
std::function<void(T)> function;
};
問題是這個模板不能為void
類型編譯,因為
void call(void type)
變得不確定。
專門針對void
類型並不能解決問題,因為
template <>
void Test<void>::call(void)
{
function();
}
仍與call(T Type)
聲明call(T Type)
不兼容。
因此,使用C ++ 11的新功能,我嘗試了std::enable_if
:
typename std::enable_if_t<std::is_void_v<T>, void> call()
{
function();
}
typename std::enable_if_t<!std::is_void_v<T>, void> call(T type)
{
function(type);
}
但它不能用Visual Studio編譯:
錯誤C2039:'type':不是'std :: enable_if'的成員
你會如何解決這個問題?
專攻全班:
template <>
struct Test<void>
{
void call()
{
function();
}
std::function<void()> function;
};
如果您不堅持使用void
,並且您的意圖是實際上能夠使用不帶任何參數的Test
,那么使用variadic模板:
template <typename ...T>
struct Test
{
void call(T ...type)
{
function(type...);
}
std::function<void(T...)> function;
};
這樣,您可以擁有任意數量的參數。 如果您想要沒有參數,請使用:
Test<> t;
t.call();
所以這不是你想要的語法,但是不需要專門化,這個解決方案更靈活,因為它支持任意數量的參數。
SFINAE不會(僅)處理類/結構的模板參數。
適用於涉及方法模板參數的模板方法。
所以你必須寫
template <typename U = T>
std::enable_if_t<std::is_void<U>::value> call()
{ function(); }
template <typename U = T>
std::enable_if_t<!std::is_void<U>::value> call(T type)
{ function(type); }
或者,如果你想確定U
是T
template <typename U = T>
std::enable_if_t< std::is_same<U, T>::value
&& std::is_void<U>::value> call()
{ function(); }
template <typename U = T>
std::enable_if_t<std::is_same<U, T>::value
&& !std::is_void<U>::value> call(T type)
{ function(type); }
ps: std::enable_if_t
是一個類型,因此之前不需要typename
。
ps2:你標記了C ++ 11,但是你的例子使用的是std::enable_if_t
,即C ++ 14和std::is_void_v
,即C ++ 17
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.