[英]Issue with SFINAE in Ideone?
我正在嘗試通過將Visual Studio的輸出與GCC的輸出進行比較來調試我在Visual Studio中遇到的問題,但我似乎無法獲得在Ideone中編譯的極其簡化的代碼版本:
#include <exception>
#include <iostream>
template <int x>
struct foo {};
template <>
struct foo<0> { using type = int; };
template <typename Foo>
struct bar
{
bar(void) {}
template <typename = typename Foo::type>
bar(const bar &) {}
};
int main(void)
{
bar<foo<1>> x;
}
當我嘗試使用Ideone運行它時,上面給出了錯誤:
prog.cpp: In instantiation of ‘struct bar<foo<1> >’:
prog.cpp:21:17: required from here
prog.cpp:16:5: error: no type named ‘type’ in ‘struct foo<1>’
bar(const bar &) {}
根據我的理解,替換Foo::type
的失敗不應導致編譯錯誤。 請注意,制作復制構造函數bar(const bar &) { typename Foo::type x; }
bar(const bar &) { typename Foo::type x; }
允許程序編譯就好了。 我試圖使用這個模板幾乎與使用std::enable_if
完全相同,這在類中的任何地方使用時也會導致編譯錯誤 - 而不僅僅是復制構造函數。 這是正確的行為嗎? 我很確定它不是,但我一直認為Ideone在后端使用GCC ......
是的,這種行為是正確的。
在函數模板重載決策期間推導模板參數時,SFINAE適用(允許編譯器丟棄特殊化而不發出錯誤)。
在您的情況下,錯誤在重載解析期間沒有發生,但在模板實例化期間: bar
模板根本無法實例化,因為復制構造函數需要存在嵌套類型Foo::type
,模板時不存在參數是foo<1>
。
對於你的最后一點,如果你聲明:
template <typename Foo>
struct bar
{
bar(void) {}
bar(const bar &) { typename Foo::type x; }
};
只要不調用復制構造函數,它就可以編譯。 使用復制構造函數將導致相同的編譯錯誤:
bar<foo<1>> x2 = x; // Error
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.