![](/img/trans.png)
[英]How to understand the following usage of boost::enable_if and boost::disable_if
[英]Boost enable/disable_if function pair's order matters?
我正在編寫一個遞歸函數,其結束條件由模板參數確定。 我正在使用boost::enable_if
和boost::disable_if
來為空的基本情況切換遞歸函數(以防止麻煩的無限實例化循環)。
問題在於它似乎取決於我定義這些功能的順序:
#include <boost/utility.hpp>
template <unsigned a, unsigned b>
typename boost::disable_if_c<a == b>::type f()
{
f<a+1,b>();
}
template <unsigned a, unsigned b>
typename boost::enable_if_c<a == b>::type f()
{
}
int main()
{
f<0,5>();
}
編譯器(g ++ 4.6)失敗,並顯示以下錯誤:
test.cpp:7:5: error: no matching function for call to ‘f()’
test.cpp:7:5: note: candidate is:
test.cpp:5:44: note: template<unsigned int a, unsigned int b> typename boost::disable_if_c<(a == b)>::type f()
由於某種原因,只有禁用的功能才是候選功能,看不到已啟用的功能。
如果我切換順序,則定義了兩個函數,它將在有問題且沒有警告的情況下進行編譯:
#include <boost/utility.hpp>
template <unsigned a, unsigned b>
typename boost::enable_if_c<a == b>::type f()
{
}
template <unsigned a, unsigned b>
typename boost::disable_if_c<a == b>::type f()
{
f<a+1,b>();
}
int main()
{
f<0,5>();
}
為什么是這樣? 到實例化發生時( main
),編譯器已經看到了這兩個函數,不必在乎誰先行。 至少那是我的想法。
你說
到實例化發生時(主要),編譯器已經看到了這兩個函數,並且不必在乎誰先入行。
這是不對的,我認為這就是讓您絆倒的原因。 main中實例化的只是f<0,5>
,其余實例化發生在您調用它們的位置,即第一個f
函數模板中。 從那里看不到第二個,所以它不能參與重載解析。
所以,會發生什么:
// imagine we're inside f<4,5> instantiation
template <unsigned a, unsigned b>
typename boost::disable_if_c<a == b>::type f()
{
f<a+1,b>(); // <-- here we attempt to instantiate f<5,5> ...
// but it gets disabled!
// and there is no other f visible here, it's defined just below
}
如果切換定義的順序,則enable_if
版本可見,並在需要時插入。
實際上,您對函數是模板感到困惑。 這與它無關。 由於相同的原因,以下代碼也不會編譯。
void foo(int)
{
foo("");
}
void foo(char const*)
{
}
int main()
{
foo(42);
}
順序很重要。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.