C++ 在模板参数列表中跳过先前的隐式模板参数,但不要跳过以后的隐式模板参数

C++ 在模板参数列表中跳过先前的隐式模板参数,但不要跳过以后的隐式模板参数,c++,templates,c++11,C++,Templates,C++11,我只是好奇: 在下面的示例中,我展示了我的意思,以代替/*implicit*/。 是否有一个解决方法将其留空?正如您所看到的,typename T不能是第一个 template<typename C1, typename C2, typename T = decltype(typename C1::value_type() * typename C2::value_type())> T dot(const C1 &v1, const C2 &v2); int mai

我只是好奇:

在下面的示例中,我展示了我的意思,以代替
/*implicit*/
。 是否有一个解决方法将其留空?正如您所看到的,typename T不能是第一个

template<typename C1, typename C2, typename T = decltype(typename C1::value_type() * typename C2::value_type())>
T dot(const C1 &v1, const C2 &v2);

int main()
{
    std::vector<float> vec1;
    std::vector<double> vec2;
    // typical:
    auto result1 = dot(vec1, vec2); // auto -> double
    // avoid numerical unstable situations:
    auto result2 = dot</*implicit*/,/*implicit*/,long double>(vec1, vec2); // auto -> long double
    //auto result2 = dot<decltype(vec1),decltype(vec2),long double>(vec1, vec2);
}
模板
T点(常数C1和v1,常数C2和v2);
int main()
{
std::vec1;
std::vec2载体;
//典型:
自动结果1=dot(vec1,vec2);//自动->双精度
//避免数值不稳定的情况:
自动结果2=点(vec1,vec2);//自动->长双精度
//自动结果2=点(vec1,vec2);
}

在最后一行中,我提供了一个不是超级膨胀的解决方案。

只需对参数重新排序,然后按条件执行:

// short notation for `std::declval<typename C::value_type&>()`
template<class C>
typename C::value_type& value_in();

// if T == void, find actual result type, else use T
template<class T, class C1, class C2>
using DotResult = typename std::conditional<std::is_void<T>::value,
    decltype(value_in<C1>() * value_in<C2>()), T>::type;

// void can't be a valid value_type
template<class T = void, class C1, class C2>
DotResult<T,C1,C2> dot(C1 const& c1, C2 const& c2);
//std::declval()的简短符号`
模板
typename C::value_type&value_in();
//如果T==void,则查找实际结果类型,否则使用T
模板
使用DotResult=typename std::conditional::type;
//void不能是有效的值\u类型
模板
点结果点(C1常数和C1,C2常数和C2);

然而,我不得不承认。。。我真的看不出它有什么用-你可以直接转换结果,或者隐式转换它<代码>长双x=点(v1,v2)

只需对参数重新排序,然后按条件执行:

// short notation for `std::declval<typename C::value_type&>()`
template<class C>
typename C::value_type& value_in();

// if T == void, find actual result type, else use T
template<class T, class C1, class C2>
using DotResult = typename std::conditional<std::is_void<T>::value,
    decltype(value_in<C1>() * value_in<C2>()), T>::type;

// void can't be a valid value_type
template<class T = void, class C1, class C2>
DotResult<T,C1,C2> dot(C1 const& c1, C2 const& c2);
//std::declval()的简短符号`
模板
typename C::value_type&value_in();
//如果T==void,则查找实际结果类型,否则使用T
模板
使用DotResult=typename std::conditional::type;
//void不能是有效的值\u类型
模板
点结果点(C1常数和C1,C2常数和C2);

然而,我不得不承认。。。我真的看不出它有什么用-你可以直接转换结果,或者隐式转换它<代码>长双x=点(v1,v2)

我认为类型不仅用作结果,还可能在内部用于操作。在
long double
上操作将产生不同于在内部使用
double
然后转换为
long double
(反之亦然:在调用时类型不固定的情况下,无条件地在内部使用
long double
可能会比使用
double
更慢,并产生不同的结果)@DavidRodríguez Dribea是从CPU转换为10字节浮点的每种浮点类型,即长双精度浮点。这种转换通常是不必要的(默认),但在某些情况下(有限元分析)
T=float
会导致数值不稳定的情况。从另一方面来说,将向量提升到
double
元素会导致超大内存块。@变色龙:我不明白为什么那个评论是针对我的。我试图告诉Xeo(也许我失败得很厉害?)有理由用不同于容器大小的尺寸进行计算,作为对他最后一段的评论,尤其是对你可以得出的结果的评论instead@DavidRodríguez dribeas Yeap.你是对的。它是指向Xeo的。我想这种类型不仅用作结果,还可能用于歌剧内部选项。在
长双精度
上操作将产生不同于在内部使用
双精度
然后转换为
长双精度
(反之亦然:在调用时类型不固定的情况下,无条件地在内部使用
long double
可能会比使用
double
更慢,并产生不同的结果)@DavidRodríguez Dribea是从CPU转换为10字节浮点的每种浮点类型,即长双精度浮点。这种转换通常是不必要的(默认),但在某些情况下(有限元分析)
T=float
会导致数值不稳定的情况。从另一方面来说,将向量提升到
double
元素会导致超大内存块。@变色龙:我不明白为什么那个评论是针对我的。我试图告诉Xeo(也许我失败得很厉害?)有理由用不同于容器大小的尺寸进行计算,作为对他最后一段的评论,尤其是对你可以得出的结果的评论instead@DavidRodr是的,你是对的,它是指向Xeo的。