我在一个项目中大量使用 SFINAE 函数,但不确定以下两种方法(样式除外)之间是否存在任何差异:
#include <cstdlib>
#include <type_traits>
#include <iostream>
template <class T, class = std::enable_if_t<std::is_same_v<T, int>>>
void foo()
{
std::cout << "method 1" << std::endl;
}
template <class T, std::enable_if_t<std::is_same_v<T, double>>* = 0>
void foo()
{
std::cout << "method 2" << std::endl;
}
int main()
{
foo<int>();
foo<double>();
std::cout << "Done...";
std::getchar();
return EXIT_SUCCESS;
}
Run Code Online (Sandbox Code Playgroud)
程序输出如预期:
method 1
method 2
Done...
Run Code Online (Sandbox Code Playgroud)
我已经看到方法 2 在 stackoverflow 中使用得更频繁,但我更喜欢方法 1。
这两种方法有什么不同吗?
我正在构建一些输入检查器,需要具有整数和/或双精度的特定函数(例如'isPrime'应该仅适用于整数).
如果我使用enable_if它作为参数它完美地工作:
template <class T>
class check
{
public:
template< class U = T>
inline static U readVal(typename std::enable_if<std::is_same<U, int>::value >::type* = 0)
{
return BuffCheck.getInt();
}
template< class U = T>
inline static U readVal(typename std::enable_if<std::is_same<U, double>::value >::type* = 0)
{
return BuffCheck.getDouble();
}
};
Run Code Online (Sandbox Code Playgroud)
但如果我将它用作模板参数(如http://en.cppreference.com/w/cpp/types/enable_if所示)
template <class T>
class check
{
public:
template< class U = T, class = typename std::enable_if<std::is_same<U, int>::value>::type >
inline static U readVal()
{
return BuffCheck.getInt();
}
template< class U …Run Code Online (Sandbox Code Playgroud) 在C++中,如果要部分地专门化模板类中的单个方法,则必须专门化整个类(例如,在模板专门化中使用带有多个模板参数的模板化类的单个方法中所述)
然而,当具有多个模板参数的较大模板类中,当它们中的每一个影响单个函数时,这变得令人厌烦.使用N个参数,您需要专门化2 ^ N次!
但是,使用C++ 11我认为可能有一个更优雅的解决方案,但我不知道如何处理它.也许不知怎的enable_if?有任何想法吗?
场景:
我有多种类型可以归类为序列容器.
所有序列容器都是数据结构,但并非每个数据结构都是序列容器.
以下是代码中说明的示例.此示例中涉及的唯一"重要类型"是Array_T.它分为两类:它是一个序列容器,由于所有序列容器都是数据结构,因此它又是一个数据结构.
//A sequence container type
class Array_T{};
//A type trait for that particular sequence container
template <typename T> struct Is_Array { static const bool value = false; };
template <> struct Is_Array<Array_T> { static const bool value = true; };
//A type trait to identify all of the sequence containers
template <typename T> struct Is_A_Sequence_Container { static const bool value = Is_Array<T>::value
/* would probably "or" together more sequence types, but we only have Array_T in this …Run Code Online (Sandbox Code Playgroud) 这只是一个关于样式的问题:我不喜欢C++模板元编程的方式,它要求你使用返回类型或为SFINAE的技巧添加额外的伪参数.所以,我提出的想法是将SFINAE事物放在模板参数定义本身中,如下所示:
#include <iostream>
#include <boost/type_traits/is_array.hpp>
#include <boost/utility/enable_if.hpp>
using namespace std;
template <typename T, typename B=typename boost::enable_if< boost::is_array<T> >::type > void asd(){
cout<<"This is for arrays"<<endl;
}
template <typename T, typename B=typename boost::disable_if< boost::is_array<T> >::type > void asd(){
cout<<"This is for NON arrays"<<endl;
}
int main() {
asd<int>();
asd<int[]>();
}
Run Code Online (Sandbox Code Playgroud)
这个例子让g ++抱怨:
../src/afg.cpp:10:97:错误:重新定义'template void asd()'
SFINAE就在那里工作,因为如果我删除例如一个disable_if,编译错误是:
../src/afg.cpp:15:12:错误:没有匹配函数来调用'asd()'
这就是我想要的.
那么,有没有办法在一个函数的"正常"签名中完成SFINAE,即返回类型+参数列表?
编辑:这最终我将在真正的代码中尝试:
#include <iostream>
#include <type_traits>
using namespace std;
template <typename T, typename enable_if< is_array<T>::value, int >::type =0 > void asd(){ …Run Code Online (Sandbox Code Playgroud) 任何人都可以让我知道实现这一目标的最佳方法.
说,我有一个模板功能
template<typename ARGUMENT>
void get_result(ARGUMENT &ag)
{
// arg can be a single object of a particular object or list of objects of that particular class.
//rest
}
Run Code Online (Sandbox Code Playgroud)
有没有办法可以检查&ag是单个对象还是对象列表.此外,使用给定的模板界面.
如果答案是通过类接口以某种方式通过模板规范并不重要.唯一的问题是我不想指定对象类型或列表类型.
防爆.ag = int或ag = list
CB
在介绍概念和约束之前,有几种方法可以模拟此编译时检查。以“ order()”功能为例:(如何在LessThanComparable没有概念或约束的情况下实施是另一回事)
使用 static_assert
template <typename T, typename U>
void order(T& a, U& b)
{
static_assert(LessThanComparable<U,T>, "oh this is not epic");
if (b < a)
{
using std::swap;
swap(a, b);
}
}
Run Code Online (Sandbox Code Playgroud)
这种方法不适用于函数重载。
使用 typename = enable_if
template <typename T, typename U,
typename = std::enable_if_t<LessThanComparable<U,T>>>>
void order(T& a, U& b)
{
if (b < a)
{
using std::swap;
swap(a, b);
}
}
Run Code Online (Sandbox Code Playgroud)
如果过分“聪明”的家伙用手指定了第三个参数怎么办?
使用enable_if的函数原型:
template <typename T, typename U>
std::enable_if_t<LessThanComparable<U,T>>, void> order(T& a, U& b) …Run Code Online (Sandbox Code Playgroud)