我有一組其接收的索引(在示例的int
)模板函數和返回給定的類型的值,我使用SFINAE從算術類型分開std::string
:爲什麼在此函數模板中替換失敗?
// 1
template <typename T>
typename std::enable_if<std::is_arithmetic<T>::value, T>::type
t(int) { ... }
// 2
template <typename T>
typename std::enable_if<std::is_same<std::string, T>::value, T>::type
t(int) { ... }
// 3
template <template <typename ...> class T, typename ... P>
T<P ...> t(int) { ... }
另外,有接收容器中,並使用上述功能,填補它的功能:
template <typename C>
C c(int)
{
C r{};
std::insert_iterator<C> iterator(r, r.begin());
*iterator = t<typename C::value_type>(0);
return r;
}
的t
目標是分辨號和串,但是如果提供了一對(因爲它來自關聯容器),那麼,t
應該將第一個和第二個類型的兩個不同的t
調用中的每個對分割。
雖然反序列化它的工作原理的非關聯容器,但使用關聯容器編譯失敗:
using vi = std::vector<int>;
using mii = std::map<int, int>;
auto o = c<vi>(0); // Deserialize vector
auto p = c<mii>(0); // Deserialize map
彙編在反序列化容器的一個元件的點失敗:
*iterator = t<typename C::value_type>(0);
對於非關聯容器C::value_type
是一種類型,其中前兩個版本的條件之一是t
,但對於關聯容器C::value_type
是一對,並且在版本#1和# 2的t
但不適用於#3版本的t
函數;問題是,它無法爲他們三人:
error: no matching function for call to 't' *iterator = t<typename C::value_type>(0); ^~~~~~~~~~~~~~~~~~~~~~~~~ note: in instantiation of function template specialization 'c<std::map<int, int>>' requested here auto p = c<mii>(0); ^ note: candidate template ignored: requirement 'std::is_arithmetic<pair<const int, int> >::value' was not satisfied [with T = std::pair<const int, int>] t(int) { ... } ^ note: candidate template ignored: requirement 'std::is_same<std::string, pair<const int, int> >::value' was not satisfied [with T = std::pair<const int, int>] t(int) { ... } ^ note: candidate template ignored: invalid explicitly-specified argument for template parameter 'T' T<P ...> t(int) { ... } ^
顯然,編譯器抱怨缺少的模板,模板參數,但是,如果我擺脫SFINAE的錯誤消失:
template <typename T>
T
t(int) { return {}; }
template <template <typename ...> class T, typename ... P>
T<P ...> t(int) { return {}; }
template <typename C>
C c(int)
{
C r{};
std::insert_iterator<C> iterator(r, r.begin());
*iterator = t<typename C::value_type>(0);
return r;
}
int main()
{
using vi = std::vector<int>;
using mii = std::map<int, int>;
auto o = c<vi>(0);
auto p = c<mii>(0);
// print 0
for (auto &v : o) std::cout << v << '\n';
// print 00
for (auto &v : p) std::cout << v.first << v.second << '\n';
return 0;
}
它看起來像SFINAE強制模板參數需要而不是推斷,爲什麼會發生這種情況?我應該如何解決它?
那麼最初的't'有兩個模板參數,新的't'只有1.你必須使用't'來調用原始的't'。 'std :: pair '不是模板模板參數的有效參數。 –
Simple
關聯容器的'value_type'通常是一個鍵/值對。關聯容器提供'mapped_type'。 –
@簡單的說,如果我擺脫了SFINAE的混亂,'t'不需要指定參數([檢查出來](https://wandbox.org/permlink/Dj96G6V15bBT2c3S))推斷出這對。 –