jav*_*ver 4 c++ sfinae template-templates c++14
如何在模板参数中检查模板模板类的类型?
B<T>并且C<T>是模板类.
我想创建一个D<class BC>可以D<B>或者的类D<C>.
只有D<B>拥有D::f().
这是我的解决方法(演示).有用.
#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;
}
Run Code Online (Sandbox Code Playgroud)
这条线#1很长很难看(Dummy用来破解).
在实际程序中,它也容易出错,特别是当B<...>并且C<...>可以有5-7个模板参数时.
有没有办法改善它?
我的梦想是: -
template<class BCLocal=BC> static
typename std::enable_if<std::is_same<BCLocal,B>::value,void>::type f(){
}
Run Code Online (Sandbox Code Playgroud)
为什么不把比较提取到一个方便的实用程序?
#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 {};
Run Code Online (Sandbox Code Playgroud)
那么SFINAE就f可以看起来像这样:
static auto f() -> typename std::enable_if<is_same_temp<BC, B>::value>::type {
}
Run Code Online (Sandbox Code Playgroud)
没有必要指定void,enable_if因为它是它给出的默认类型.
我认为尾随返回类型也具有美化效果.
使用C++ 14,我们可以进一步美化.首先是变量模板.
template<template<class...> class L, template<class...> class R>
using bool const is_same_temp_v = is_same_temp<L, R>::value;
Run Code Online (Sandbox Code Playgroud)
然后使用std::enable_if_t模板别名:
static auto f() -> std::enable_if_t<is_same_temp_v<BC, B>> {
}
Run Code Online (Sandbox Code Playgroud)