C++ 如果使用constexpr bool测试不起作用,则启用
我有一个数学函数,我希望能够接受一个double,或者一个double的数组/向量/容器,并且行为稍微不同 我试图使用SFINAE和type traits来选择正确的函数 下面是一个简单的例子:C++ 如果使用constexpr bool测试不起作用,则启用,c++,c++11,templates,constexpr,enable-if,C++,C++11,Templates,Constexpr,Enable If,我有一个数学函数,我希望能够接受一个double,或者一个double的数组/向量/容器,并且行为稍微不同 我试图使用SFINAE和type traits来选择正确的函数 下面是一个简单的例子: #include <iostream> #include <vector> #include <type_traits> template <typename T> constexpr bool Iscontainer() { if conste
#include <iostream>
#include <vector>
#include <type_traits>
template <typename T>
constexpr bool Iscontainer()
{
if constexpr (std::is_class<T>::value && std::is_arithmetic<typename T::value_type>::value) {
return true;
}
return false;
}
// Function 1 (double):
template <typename T>
typename std::enable_if<std::is_arithmetic<T>::value>::type g(T const & t)
{
std::cout << "this is for a double" << t << std::endl;
}
// Function 2 (vec), version 1:
template <typename T>
typename std::enable_if<IsContainer<T>()>::type g(T const & t)
{
std::cout << "this is for a container" << t[0] << std::endl;
}
int main()
{
std::vector<double> v {1, 2};
std::array<double, 2> a {1, 2};
double d {0.1};
g<>(v);
g<>(a);
g<>(d); // error here
}
#包括
#包括
#包括
模板
constexpr bool Iscontainer()
{
如果constexpr(std::is_class::value&&std::is_算术::value){
返回true;
}
返回false;
}
//职能1(双重):
模板
typename std::enable_if::type g(T const&T)
{
std::cout似乎简单的重载完成了这项工作:
template <typename T>
void g(T const & t)
{
std::cout << "this is for a double" << t << std::endl;
}
template <typename T>
void g(const std::vector<T>& t)
{
std::cout << "this is for a vector" << t[0] << std::endl;
}
您的第二个版本使用SFINAE
// Function 2 (vec), version 2:
template <typename T>
typename std::enable_if<std::is_class<T>::value
&& std::is_arithmetic<typename T::value_type>::value>::type
// SFINAE happens here for double ^^^^^^^^^^^^^
g(T const & t)
//函数2(vec),第2版:
模板
typename std::enable_if::type
//SFINAE在这里举行双人比赛^^^^^^^^^^^^^
g(施工及测试)
失败的原因很简单。您不调用SFINAE,当编译器尝试计算它看到的表达式时:
if constexpr (std::is_class<double>::value // this is fine it's false
&& std::is_arithmetic<typename double::value_type>::value // problem here!
)
或者,我建议使用别名:
template <typename T>
using IsVector2 = std::conjunction<typename std::is_class<T>, std::is_arithmetic<typename T::value_type> >;
template <typename T>
typename std::enable_if<IsVector2<T>::value>::type g(T const & t)
{
std::cout << "this is for a vector" << t[0] << std::endl;
}
模板
使用IsVector2=std::conjunction;
模板
typename std::enable_if::type g(T const&T)
{
std::cout-hmm,这是真的,如果我想让它也适用于std::数组呢?仍然对为什么它不起作用感兴趣work@dddd4那么添加另一个重载?我不知道的提供[]的类型呢与他们的数据接口?@dddd4:我还添加了使用代码解决问题的说明。因此,您的traits函数也不是您所期望的,您可能需要traits具有_方括号(traits运算符
或类似运算符。
// Function 2 (vec), version 2:
template <typename T>
typename std::enable_if<std::is_class<T>::value
&& std::is_arithmetic<typename T::value_type>::value>::type
// SFINAE happens here for double ^^^^^^^^^^^^^
g(T const & t)
if constexpr (std::is_class<double>::value // this is fine it's false
&& std::is_arithmetic<typename double::value_type>::value // problem here!
)
#include <iostream>
#include <vector>
#include <type_traits>
template <typename T>
constexpr bool IsVector()
{
if constexpr (std::is_class<T>::value) {
if constexpr (std::is_arithmetic<typename T::value_type>::value) {
return true;
}
}
return false;
}
// Function 1 (double):
template <typename T>
typename std::enable_if<std::is_arithmetic<T>::value>::type g(T const & t)
{
std::cout << "this is for a double" << t << std::endl;
}
// Function 2 (vec), version 1:
template <typename T>
typename std::enable_if<IsVector<T>()>::type g(T const & t)
{
std::cout << "this is for a vector" << t[0] << std::endl;
}
int main()
{
std::vector<double> v {1, 2};
double d {0.1};
g<>(v);
g<>(d); // error here
}
template <typename T>
using IsVector2 = std::conjunction<typename std::is_class<T>, std::is_arithmetic<typename T::value_type> >;
template <typename T>
typename std::enable_if<IsVector2<T>::value>::type g(T const & t)
{
std::cout << "this is for a vector" << t[0] << std::endl;
}