可变参数模板类-0长度的包构造函数冲突

时间:2019-07-14 19:52:11

标签: c++ variadic-templates sfinae

给予

template<class... Args>
struct foo {

    function<void(Args...)>     m_function;
    unique_ptr<tuple<Args...>>  m_args;

    foo(const std::function<void(Args...)>& func, Args... args) :
        m_function{ func }, m_args{ new tuple<Args...>(args...) } {

        cout << "ctor 1" << endl;
    }

    // <some template wizardry here>
    foo(const std::function<void(Args...)>& func) :
        m_function{ func } {

        cout << "ctor 2" << endl;
    }
};

我希望仅在sizeof...(Args) != 0时实例化ctor2(否则会发生冲突..)。

此功能似乎可以正常工作(无碰撞)

template<Args...>
foo(const std::function<void(Args...)>& func) :
    m_function{ func } {

    cout << "ctor 2" << endl;
}

但是我不知道它为什么/为什么可靠。

我可能也使用类似

std::enable_if<sizeof...(Args) != 0, ???>

如何使用std::enable_if解决此问题以及我的第二个代码示例中发生了什么?

2 个答案:

答案 0 :(得分:3)

https://github.com/card-io/card.io-Android-source

答案 1 :(得分:3)

正如Johannes Schaub-litb在评论中指出的那样,您可以简单地添加一个未使用的模板参数的可变列表,只是将您的第二个构造器转换为一个模板,并将优先级(避免冲突)赋予第一个不是模板构造函数。

所以您可以简单地写

template <typename ...>
foo (std::function<void(Args...)> const & func)
    : m_function{ func }
 { std::cout << "ctor 2" << std::endl; }

但是要满足您的要求

  

我希望仅在sizeof...(Args) != 0

时实例化ctor2

您可以尝试(不太优雅,但也许更容易理解)

template <bool B = (sizeof...(Args) > 0u),
          std::enable_if_t<B, bool> = true>
foo (std::function<void(Args...)> const & func)
    : m_function{ func }
 { std::cout << "ctor 2" << std::endl; }