![](/img/trans.png)
[英]Conditionally invalid member function of class template (implicit instantiation works; explicit instantiation fails)
[英]Why class template instantiation fails for unused member template function
這有什么問題:
#include <type_traits>
struct A;
template<typename T>
struct B
{
template<typename=std::enable_if<std::is_copy_constructible<T>::value>>
void f1() {}
};
template<typename T>
struct C {};
// Type your code here, or load an example.
int main() {
// Following fails
B<A> b;
// Could use this:
// b.f1<C>();
// This complies
C<A> c;
return 0;
}
/* This to be in or not doesn't make a difference
struct A
{};
*/
我在這里試過這個: https://godbolt.org/z/NkL44s使用不同的編譯器:
那么為什么最近的編譯器會拒絕這個呢? 在實例化B<A>
時,不清楚f1
將以哪種形式使用,或者是否會使用它。 那么為什么編譯器會抱怨呢? f1
成員模板function不應該只有在真的使用時才檢查?
編輯:
正如評論中提到的,我在上面的代碼中犯了一個無意的錯誤: std::enable_if
應該是std::enable_if_t
,就像在這個更正的游樂場中一樣: https://godbolt.org/z/cyuB3d
這改變了編譯器無錯誤地傳遞此代碼的情況:
但是,問題仍然存在:為什么從未使用過的 function 的默認模板參數會導致編譯失敗?
原因是std::is_constructible
需要一個完整的類型:( 表 42 )
模板
template <class T> struct is_copy_constructible;
前提條件
T
應為完整類型、 cv void 或未知邊界數組。
未能滿足庫“應”要求會導致未定義的行為。
從is_copy_constructible<T>
上的cppreference :
T 應該是一個完整的類型,(可能是 cv 限定的)void,或者一個未知邊界的數組。 否則,行為未定義。
因此,您似乎在較舊的編譯器版本中只有普通的 UB,而較新的編譯器版本足以告訴您A
必須是完整的類型。
請注意,在存在 UB 的情況下,編譯器不需要發出錯誤,但他們可能會這樣做,這是一件好事。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.