我有一组其接收的索引(在示例的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))推断出这对。 –