template < typename...dummy >
class wrapper;
template < typename TYPE >
class wrapper < TYPE > {};
template < template < typename... > class TYPE, typename... PARAMS >
class wrapper < TYPE < PARAMS... > > {};
template < typename >
class templated_class {};
class normal_class {};
typedef wrapper < normal_class > normal_wrapper;
typedef wrapper < templated_class, int > templated_wrapper;
在错误
中明显编译上述结果 'templated_class': class template ( not specialized ) cannot be a template argument for 'dummy', an actual type was expected
如何让它发挥作用,以便wrapper
可以接受normal_class
和templated_class
作为第一个参数?我觉得有一个简单的方法,但我没有看到它,因为我太挂了问题。
我不能写的原因
typedef wrapper < templated_class < int > > templated_wrapper;
是因为typedef是由一个可变参数宏创建的,为了MCVE目的而剥离 - 看起来像这样:
#define first_va(f,...) f
#define createwrapper(...) \
typedef wrapper < __VA_ARGS__ > first_va(__VA_ARGS__)_wrapper;
createwrapper(normal_class)
createwrapper(templated_class,int)
我不知道如何执行预处理器向导以在<>
中的第一个之后包含所有参数,如果可能的话。
使用模板或宏的解决方案对我来说都是可以接受的,尽管我更喜欢模板解决方案。
答案 0 :(得分:2)
#define createwrapper_single(f) \
typedef wrapper<f> f##_wrapper;
#define createwrapper_multiple(f, ...) \
typedef wrapper<f<__VA_ARGS__> > f##_wrapper;
#define pick_createwrapper(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, NAME, ...) NAME
#define createwrapper(...) \
pick_createwrapper(__VA_ARGS__, createwrapper_multiple, createwrapper_multiple, \
createwrapper_multiple, createwrapper_multiple, createwrapper_multiple, \
createwrapper_multiple, createwrapper_multiple, createwrapper_multiple, \
createwrapper_multiple, createwrapper_single, something_is_wrong_if_this_is_used)(__VA_ARGS__)
Demo。显然,如果你写的模板有超过9个参数,那么这会破坏,但你可以根据需要将它扩展到任意数量。
或者,您可以使用decltype
和重载功能:
template <template < typename... > class T, typename... params>
wrapper<T<params...>> wrapper_helper();
template <typename T>
wrapper<T> wrapper_helper();
#define first_va(f,...) f
#define PASTE2(x, y) x##y
#define PASTE(x, y) PASTE2(x,y)
#define createwrapper(...) \
typedef decltype(wrapper_helper< __VA_ARGS__ >()) \
PASTE(first_va(__VA_ARGS__,_blank), _wrapper);
答案 1 :(得分:0)
你不能拥有它。一旦定义了具有简单typename
类型的所有参数的模板(不是模板而不是值),所有特化都必须使用类型作为实际模板参数。相反,如果参数是模板,则相应的参数将始终是任何特化中的模板。也就是说,没有为类模板重载。
您正在尝试做不可能的事情,因为您混淆了部分特化中存在的两个括号分隔列表。我想我只是用代码live demo here来解释它。
#include <iostream>
template <typename...> // <--- to instantiate, say `wrapper<whatever list of types>`
struct wrapper
{
static void foo() {
std::cout << "generic" << std::endl;
}
};
template<typename T>
struct wrapper<T> // <--- to instantiate, say `wrapper<sometype>`
{
static void foo() {
std::cout << "one argument" << std::endl;
}
};
// just an illustration
template <typename T> // <--------------------------------------------------+
struct wrapper <int, double, T> // <--- to instantiate, use this list of arguments |
{ // not this one -----------------------------+
// that is, say `wrapper<int, double, sometype>`
// not `wrapper<sometype>`
static void foo() {
std::cout << "three arguments (int, double, something)" << std::endl;
}
};
template <template<typename ...> class T, // <-----------------------------------------+
typename K> // |
struct wrapper<T<K>> // <--- to instantiate, use this list of arguments |
{ // not this one ------------------------------+
// that is, say `wrapper<sometemplate<sometype>>`
static void foo() {
std::cout << "the template thingy" << std::endl;
}
};
template <typename> class X {};
int main ()
{
wrapper<int, int>::foo();
wrapper<int>::foo();
wrapper<int, double, X<int>>::foo();
wrapper<X<int>>::foo();
}