C++:试图在类中封装std::enable_if
C++: Trying to encapsulate std::enable_if in class
我刚用SFINAE选择函数模板,就有了将std::enable_if
封装在这样的结构中的绝妙想法
template<typename T, typename U>
struct EnableWhenEqual
{
typedef typename std::enable_if<std::is_same<T, U>::value>::type type;
};
然后使用它,例如,像这个
template<typename T, typename U, typename Enable = EnableWhenEqual<T,U>::type >
void foo(T&& t, U&& u)
{
if (std::is_same<T,U>::value)
std::cout << "OK, overload allowed." << std::endl;
else
std::cout << "Bad. Should not compile!" << std::endl;
}
然而,这并不起作用,正如调用所看到的那样
foo(1,1); //prints "OK, overload allowed"
foo(1,2.0); //prints "Bad, should not compile", but obviously does
另一方面,通过尝试创建
EnableWhenEqual<int,int>(); //compiles
EnableWhenEqual<int,double>(); //does not compile because type does not exist
得到一个编译器错误("type不是std::enableif的成员")。
这种行为的原因是什么?我这么问是因为根据我对SFINAE的了解,我会认为类型推导中的错误会导致过载被排除?
为了完整性,可以使用模板混叠来解决上述问题
template <typename T, typename U>
using EnableWhenEqual = typename std::enable_if<std::is_same<T,U>::value>::type;
是否还有使用结构而不是模板别名的替代方法?
EDIT:这里我指的是解决一般问题的实现。例如,这里的
template<typename T, typename U, bool B, typename C=void>
struct EnableWhenEqual {};
template<typename T, typename U, typename C>
struct EnableWhenEqual<T,U,std::is_same<T,U>::value>
{
typedef typename C type;
};
不适用于我,因为部分专用化需要一个简单的标识符。如果可以的话,可以用一般结构Condition<T,U>
来代替std::is_same
。有其他选择吗?
这应该可以做到:
template<typename T, typename U>
struct EnableWhenEqual : std::enable_if<std::is_same<T, U>::value>
{
};
http://coliru.stacked-crooked.com/a/650202ba3d42d34b
一种不同类型的封装:
template<class T, class U>
using EnableWhenEqual_t = typename std::enable_if< std::is_same<T,U>::value >::type;
template<typename T, typename U, typename Enable = EnableWhenEqual_t<T,U> >
void foo(T&& t, U&& u) {
if (std::is_same<T,U>::value)
std::cout << "OK, overload allowed." << std::endl;
else
std::cout << "Bad. Should not compile!" << std::endl;
}
请注意,当您询问有关模板VS处理的问题时,请包括确切的visual studio版本。VS模板支持非常古怪。
相关文章:
- 使用std::multimap迭代器创建std::list
- C++中std::resize(n)和std::shrink_to_fit之间的区别
- 来自 std::list 的迭代器 .end() 按预期返回"0xcdcdcdcdcdcdcdcd"但 .begin()
- C++17复制构造函数,在std::unordereded_map上进行深度复制
- 如何导出包含具有"std::unique_ptr"值的"std::map"属性的
- 从持续时间构造std::chrono::system_clock::time_point
- std::具有相同基类的类的变体
- std::向量与传递值的动态数组
- 使用std::vector的OpenCL矩阵乘法
- std::map<struct,struct>::find 找不到匹配项,但是如果我循环通过 begin() 到 end(),我在那里看到匹配项
- std::condition_variable::wait()如何评估给定的谓词
- 如何获取std::result_of函数的返回类型
- std::原子加载和存储都需要吗
- 将对象移动到std::shared_ptr
- POCO::PostgreSQL:如何将std::vector支持添加到`Binder::bind`
- 使用一个考虑到std::map中键值的滚动或换行的键
- 如何从 std::atomic 中提取指针 T<T>?
- 为什么 std::unique 不调用 std::sort?
- 使用std::函数映射对象方法
- Linux gnu++11,在运行时获取"Enable multithreading to use std::thread: Operation not permitted"