簡體   English   中英

模板 ID 不匹配任何模板聲明

[英]template-id does not match any template declaration

我不確定為什么TCollectionsize函數模板的專業化失敗。

template <typename C>
using detect_size = decltype(std::declval<C>().size());

template <typename C>
constexpr auto size(const C& c) -> decltype(c.size()) { return c.size(); }

template <typename C>
inline std::enable_if_t<
  !is_detected<detect_size,C>::value, size_t >
size(const C& c) { return std::distance( std::begin(c), std::end(c) ); }

template <class T, size_t N>
constexpr size_t size(const T (&array)[N]) noexcept { return N; }

template <>
auto size<TCollection>(const TCollection& c) { return c.GetSize(); }

GCC 給了我

error: template-id 'size<TCollection>' for 'auto size(const TCollection&)'
does not match any template declaration

is_detected這里實現。

編輯:

  • 明確指定返回類型不會改變任何東西;
  • 如果我使用重載,則使用std::distance的實現會被選中。

重載代碼:

auto size(const TCollection& c) { return c.GetSize(); }

您必須為您的專業化使用與通用模板完全相同的聲明,因此:

template <>
std::enable_if_t<!is_detected<detect_size, TCollection>::value, size_t >
size<TCollection>(const TCollection& c) { return c.GetSize(); }

更簡單的是使用重載:

auto size(const TCollection& c) { return c.GetSize(); }

演示

Jarod42 的回答僅部分適用於我的情況。

有兩件事我沒有意識到:

  1. 函數模板特化必須返回與基本情況相同的類型。

返回類型的確切拼寫方式並不重要。 所以,而不是 Jarod42 建議的定義

template <>
std::enable_if_t<!is_detected<detect_size, TCollection>::value, size_t >
size<TCollection>(const TCollection& c) { return c.GetSize(); }

寫就夠了

template <>
size_t size(const TCollection& c) { return c.GetSize(); }
  1. 如果它的定義出現在函數調用之后,則重載將不起作用。

如果代碼結構如下:

template <typename T>
size_t size(const T& x) { return x.size(); }

template <typename T>
std::vector<int> reserve_same_number_of_ints(const T& x) {
  std::vector<int> vec;
  vec.reserve(size(x));
  return vec;
}

/* specialize or overload here for special_type */

/* call reserve_same_number_of_ints on the special_type */

選擇了模板特化,但沒有選擇重載。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM