SFINAE 优雅地检查 "template template class"(在模板参数中)
SFINAE to check "template template class" (in template argument) elegantly
如何在模板参数中检查模板模板的类型 class?
例子
B<T>
和 C<T>
是模板 class。
我想创建一个 class D<class BC>
可以是 D<B>
或 D<C>
.
只有 D<B>
有 D::f()
.
这是我的解决方法 (demo)。有效。
#include <iostream>
using namespace std;
class Dummy{};
template<class T>class B{};
template<class T>class C{};
template<template<class T> class BC>class D{
//f() is instantiated only if "BC" == "B"
public: template<class BCLocal=BC<Dummy>> static
typename std::enable_if<std::is_same<BCLocal,B<Dummy>>::value,void>::type f(){
}
//^ #1
};
int main() {
D<B>::f();
//D<C>::f(); //compile error as expected, which is good
return 0;
}
#1
行又长又丑(使用 Dummy
破解)。
在实际程序中,它也很容易出错,尤其是当 B<...>
和 C<...>
可以有 5-7 个模板参数时。
有什么方法可以改善吗?
我梦想着这样的东西:-
template<class BCLocal=BC> static
typename std::enable_if<std::is_same<BCLocal,B>::value,void>::type f(){
}
为什么不直接将比较提取到方便的实用程序中呢?
#include <type_traits>
template<template<class...> class L, template<class...> class R>
struct is_same_temp : std::false_type {};
template<template<class...> class T>
struct is_same_temp<T, T> : std::true_type {};
然后 f
上的 SFINAE 可以简单地看起来像这样:
static auto f() -> typename std::enable_if<is_same_temp<BC, B>::value>::type {
}
无需为 enable_if
指定 void
,因为它是它提供的默认类型。
而且后面的return类型我觉得也有美化效果。
使用 C++14,我们可以进一步美化。首先是一个变量模板。
template<template<class...> class L, template<class...> class R>
using bool const is_same_temp_v = is_same_temp<L, R>::value;
然后使用 std::enable_if_t
模板别名:
static auto f() -> std::enable_if_t<is_same_temp_v<BC, B>> {
}
如何在模板参数中检查模板模板的类型 class?
例子
B<T>
和 C<T>
是模板 class。
我想创建一个 class D<class BC>
可以是 D<B>
或 D<C>
.
只有 D<B>
有 D::f()
.
这是我的解决方法 (demo)。有效。
#include <iostream>
using namespace std;
class Dummy{};
template<class T>class B{};
template<class T>class C{};
template<template<class T> class BC>class D{
//f() is instantiated only if "BC" == "B"
public: template<class BCLocal=BC<Dummy>> static
typename std::enable_if<std::is_same<BCLocal,B<Dummy>>::value,void>::type f(){
}
//^ #1
};
int main() {
D<B>::f();
//D<C>::f(); //compile error as expected, which is good
return 0;
}
#1
行又长又丑(使用 Dummy
破解)。
在实际程序中,它也很容易出错,尤其是当 B<...>
和 C<...>
可以有 5-7 个模板参数时。
有什么方法可以改善吗?
我梦想着这样的东西:-
template<class BCLocal=BC> static
typename std::enable_if<std::is_same<BCLocal,B>::value,void>::type f(){
}
为什么不直接将比较提取到方便的实用程序中呢?
#include <type_traits>
template<template<class...> class L, template<class...> class R>
struct is_same_temp : std::false_type {};
template<template<class...> class T>
struct is_same_temp<T, T> : std::true_type {};
然后 f
上的 SFINAE 可以简单地看起来像这样:
static auto f() -> typename std::enable_if<is_same_temp<BC, B>::value>::type {
}
无需为 enable_if
指定 void
,因为它是它提供的默认类型。
而且后面的return类型我觉得也有美化效果。
使用 C++14,我们可以进一步美化。首先是一个变量模板。
template<template<class...> class L, template<class...> class R>
using bool const is_same_temp_v = is_same_temp<L, R>::value;
然后使用 std::enable_if_t
模板别名:
static auto f() -> std::enable_if_t<is_same_temp_v<BC, B>> {
}