C++ 使用enable_if专门化结构模板

C++ 使用enable_if专门化结构模板,c++,sfinae,enable-if,C++,Sfinae,Enable If,我正在尝试创建一个模板类,该类将使用不同的签名实现回调,具体取决于它是使用一种类型实例化还是使用两种类型实例化 struct NoIntermediate { }; template<typename R, typename I> struct ParserCallbackSwitch { using type = std::function<bool(const std::string &, R&, I&)>; } template

我正在尝试创建一个模板类,该类将使用不同的签名实现回调,具体取决于它是使用一种类型实例化还是使用两种类型实例化

struct NoIntermediate
{
};

template<typename R, typename I>
struct ParserCallbackSwitch
{
     using type = std::function<bool(const std::string &, R&, I&)>;
}

template<typename R, typename I = NoIntermediate>
class OtherClass
{
public:
    typedef ParserCallbackSwitch<R, I>::type ParserType;

}

所以!您没有正确地专门化模板。您正在定义两个不相关的类模板,它们恰好具有相同的名称

有多种方法可以实现你的建议。这一个为最不专门化的模板提供了一个参数包

#include <functional>
#include <type_traits>

template<typename... S>
struct OtherClass;

template<typename R, typename I>
struct OtherClass<R, I> {
    using ParserType = std::function<bool(std::string&, R&, I&)>;
};

template<typename R>
struct OtherClass<R> {
    using ParserType = std::function<bool(std::string&, R&)>;
};

int main(void) {
    static_assert(std::is_same<OtherClass<int, float>::ParserType,
                            std::function<bool(std::string&, int&,
                                                float&)>>(),
                "Something wrong here.");
    static_assert(std::is_same<OtherClass<int>::ParserType,
                            std::function<bool(std::string&, int&)>>(),
                "Hmmmmmm.");
    return 0;
}
在参数中使用默认类型的想法也行得通,但语法有点不正确。下面是它的样子

#include <functional>
#include <type_traits>

template<typename R, typename I = void>
struct OtherClass {
    using ParserType = std::function<bool(std::string&, R&, I&)>;
};

template<typename R>
struct OtherClass<R, void> {
    using ParserType = std::function<bool(std::string&, R&)>;
};

int main(void) {
    static_assert(std::is_same<OtherClass<int, float>::ParserType,
                            std::function<bool(std::string&, int&,
                                                float&)>>(),
                "Something wrong here.");
    static_assert(std::is_same<OtherClass<int>::ParserType,
                            std::function<bool(std::string&, int&)>>(),
                "Hmmmmmm.");
    return 0;
}

也许你想要一个?关闭,但我不能使用void,因为在代码的另一部分,我使用它作为函数的参数。如果我使用struct NoIntermediate{}的默认值,那么第二种方法可以很好地工作;我将把我最终使用的代码放在上面。谢谢
struct NoIntermediate {};

template<typename R, typename I = NoIntermediate>
struct ParserCallbackSwitch
{
    using type = std::function<bool(const std::string &, R&, I&)>;
};

template<typename R> 
struct ParserCallbackSwitch<R, NoIntermediate>
{
    using type = std::function<bool(const std::string &, R&)>;
};

template<typename R, typename I = NoIntermediate>
class OtherClass
{
   public:
   typedef ParserCallbackSwitch<R, I>::type ParserType;
}
#include <functional>
#include <type_traits>

template<typename... S>
struct OtherClass;

template<typename R, typename I>
struct OtherClass<R, I> {
    using ParserType = std::function<bool(std::string&, R&, I&)>;
};

template<typename R>
struct OtherClass<R> {
    using ParserType = std::function<bool(std::string&, R&)>;
};

int main(void) {
    static_assert(std::is_same<OtherClass<int, float>::ParserType,
                            std::function<bool(std::string&, int&,
                                                float&)>>(),
                "Something wrong here.");
    static_assert(std::is_same<OtherClass<int>::ParserType,
                            std::function<bool(std::string&, int&)>>(),
                "Hmmmmmm.");
    return 0;
}
#include <functional>
#include <type_traits>

template<typename R, typename I = void>
struct OtherClass {
    using ParserType = std::function<bool(std::string&, R&, I&)>;
};

template<typename R>
struct OtherClass<R, void> {
    using ParserType = std::function<bool(std::string&, R&)>;
};

int main(void) {
    static_assert(std::is_same<OtherClass<int, float>::ParserType,
                            std::function<bool(std::string&, int&,
                                                float&)>>(),
                "Something wrong here.");
    static_assert(std::is_same<OtherClass<int>::ParserType,
                            std::function<bool(std::string&, int&)>>(),
                "Hmmmmmm.");
    return 0;
}