C++ 具有专用和非专用类型的模板重载

C++ 具有专用和非专用类型的模板重载,c++,templates,C++,Templates,是因为typedef是由一个可变宏创建的,该宏为MCVE目的而剥离,如下所示: typedef wrapper < templated_class < int > > templated_wrapper; #定义第一个_va(f,…)f #定义createwrapper(…)\ typedef包装第一个\u-VA(\uu-VA\u-ARGS\uu)\u包装; createwrapper(普通类) createwrapper(模板化的_类,int) 如果可能的话,我不知

是因为typedef是由一个可变宏创建的,该宏为MCVE目的而剥离,如下所示:

typedef wrapper < templated_class < int > > templated_wrapper;
#定义第一个_va(f,…)f
#定义createwrapper(…)\
typedef包装<\uuu-VA\u-ARGS\uuu>第一个\u-VA(\uu-VA\u-ARGS\uu)\u包装;
createwrapper(普通类)
createwrapper(模板化的_类,int)
如果可能的话,我不知道如何执行预处理器向导,在
中的第一个参数之后包含所有参数

使用模板或宏的解决方案对我来说都是可以接受的,尽管我更喜欢使用模板解决方案

#define first_va(f,...) f
#define createwrapper(...) \
    typedef wrapper < __VA_ARGS__ > first_va(__VA_ARGS__)_wrapper;

createwrapper(normal_class)
createwrapper(templated_class,int)

.

你不能拥有它。一旦定义了一个模板,该模板的所有参数都是simple
typename
kind(不是模板,也不是值),所有专门化都必须使用类型作为实际的模板参数。相反,如果参数是模板,则在任何专门化中,相应的参数始终是模板。也就是说,类模板没有重载

您正试图做不可能的事情,因为您混淆了部分专门化中存在的两个括号分隔列表。我想我会用代码来解释

#包括

模板//最后一个typedef需要一个额外的typename。。。此时,templated_类不是一种类型(但templated_类是),因此指定
包装器
允许编译器不立即查找
templated_类
。。。。。哦,您可能需要扩展wrapper-
模板类templated_wrapper:public wrapper{}作为另一个模板类,您不能重载类模板,只能进行专门化。当您进行专门化时,无法更改Temole参数的类型。@Fox
typedef wrappertemplated_wrapper
会产生相同的错误消息(visual studio 2013)。我不确定你的
模板化的包装器在我的问题中有什么用途。Slyps-基本错误是-你说这个新类是包装器,而没有说什么是goo(编译器的包中有goo和wrapper,可在需要时用于int和float,但goo或wrapper本身不是有效的…或固体…类型)。您可以使用SFINAE或简单类继承而不是typedef。如果您说我想将某种类型的goo扩展到某种类型的模板化_包装器中,那么它就知道它是一个模板。@n.m.&Fox:我的问题不是“为什么”出现此错误,我想我是说“显然会导致错误”的意思在宏解决方案中很好的技巧解决了我的问题,判断是否有超过1个参数被用来写。用@ Dyp想法我在写DeCype版本的中间,但是你快了。+ 1
#define first_va(f,...) f
#define createwrapper(...) \
    typedef wrapper < __VA_ARGS__ > first_va(__VA_ARGS__)_wrapper;

createwrapper(normal_class)
createwrapper(templated_class,int)
#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__)
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);
#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();
}