使用enable_if专门化结构模板

Specializing struct template using enable_if

本文关键字:结构 专门化 if enable 使用      更新时间:2023-10-16

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

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;
}

现在,我想添加代码,以便在实例化"其他班级"时未指定,parsercallbackswitch将是:

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

请注意,在这种情况下,ParserCallbackSwitch ::类型是一个函数,只有两个参数。

我希望能够执行以下操作:

OtherClass<int, float> p; // p::ParserType = std::function<bool(std::string &, int &, float &);
OtherClass<int> q;        // q::ParserType = std::function<bool(std::string &, int &);

我无法弄清楚我是类型 NoIntermediate的情况(即未指定)的情况下的 ParserCallbackSwitch

解决方案:基于下面的响应。这是我最终使用的代码。

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;
}

so!您无法适当地专门使用模板。您正在定义两个恰好具有相同名称的无关类模板。

有多种方法可以做您建议的事情。这给出了最不专业的模板一个参数包。

#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;
}