据我所知,我想限制以下类的2种类型int和string,就像在带有extends的java模板定义中一样。
from scrapy.utils.log import configure_logging
class MySpider(scrapy.Spider):
#ommited
def __init__(self):
configure_logging({'LOG_FILE' : "logs/mylog.log"})
但如果我像下面那样实例化
template<typename T>
typename std::enable_if<std::is_same<T,int>::value || std::is_same<T,string>::value>::type
class ExchangeSort
{
public:
void bubbleSort(T buffer[], int s);
void print(T buffer[], int s);
void bubbleSort(const vector<T>& vec);
};
我收到上述行的错误ExchangeSort未定义。有什么问题?
答案 0 :(得分:1)
SFINAE可用于有条件地禁用函数重载或模板特化。尝试使用它来禁用类模板是没有意义的,因为类模板不能重载。你最好使用静态断言:
template<typename T>
class ExchangeSort
{
static_assert(std::is_same<T,int>::value || std::is_same<T,string>::value, "ExchangeSort requires int or string");
public:
// The rest as before
至于你得到的错误,代码没有语法意义。 enable_if
只能出现在预期类型的位置。对于函数,它通常用于包装返回类型,在这种情况下,它在语法上与您编写的类似。但是对于类,template
和类定义之间没有类型。
答案 1 :(得分:0)
这是另一种允许在线下添加更多专业化的方法:
#include <type_traits>
#include <vector>
#include <string>
//
// Step 1 : polyfill missing c++17 concepts
//
namespace notstd {
template<class...> struct disjunction : std::false_type { };
template<class B1> struct disjunction<B1> : B1 { };
template<class B1, class... Bn>
struct disjunction<B1, Bn...>
: std::conditional_t<bool(B1::value), B1, disjunction<Bn...>> { };
}
//
// Step 2 : create a test to see if a type is in a list
//
namespace detail {
template<class T, class...Us>
struct is_one_of : notstd::disjunction< std::is_same<T, Us>... > {};
}
template<class T, class...Us>
static constexpr auto IsOneOf = detail::is_one_of<T, Us...>::value;
//
// Step 3 : declare the default specialisation, but don't define it
//
template<class T, typename Enable = void>
struct ExchangeSort;
//
// Step 4 : define the specialisations we want
//
template<typename T>
class ExchangeSort<T, std::enable_if_t<IsOneOf<T, int, std::string>>>
{
public:
void bubbleSort(T buffer[], int s);
void print(T buffer[], int s);
void bubbleSort(const std::vector<T>& vec);
};
//
// Test
//
int main()
{
auto esi = ExchangeSort<int>();
auto ess = ExchangeSort<std::string>();
// won't compile
// auto esd = ExchangeSort<double>();
}