c++ - 模板化成员函数和参数转发

标签 c++ templates perfect-forwarding

我在我的 C++ Playground 上玩容器,我遇到了相当技术性的问题。

我正在尝试为容器实现一个 emplace 方法。现在它应该接受一个已经构建的元素并将其传递给分配器构造方法。

我最终得到了三种方法,模板化的 emplaceA 和一对 emplaceB1emplaceB2。所有工作均按预期进行。

我的问题是 emplaceA 没有明确声明 Arg 只能是 T(这就是我想要的)。而 emplaceB1emplaceB2 在两个不同的地方提供了几乎相同的实现(我认为这是一个缺陷)。

有解决办法吗?

template<class T, class A> class container {
public:
    using allocator_traits  = typename std::allocator_traits<A>;
...
    template<class Arg> void emplaceA (int n, Arg&& arg){
        allocator_traits::construct(allocator_, data_+n, std::forward<Arg>(arg));};

    void emplaceB1(int n, const T& t){
        allocator_traits::construct(allocator_, data_+n, t);};

    void emplaceB2(int n, T&& t){
        allocator_traits::construct(allocator_, data_+n, std::move(t));};
...
};

最佳答案

要限制模板化函数,您可以使用 sfinae 来防止发送不需要的类型。

在下面的示例中,我们将您的模板函数限制为仅在 Arg 时才可调用。可转换为 T .注意 is_convertible即使两种类型相同也能正常工作。

template<class Arg, std::enable_if_t<std::is_convertible<Arg, T>::value, int> = 0>
void emplaceA(int n, Arg&& arg){
    // ...
}

不要忘记包含标题 <type_traits>


当然,如果要检查发送的类型是否严格T , 你可能想使用 std::is_same与腐烂的类型。

template<class Arg, std::enable_if_t<std::is_same<std::decay_t<Arg>, T>::value, int> = 0>
void emplaceA(int n, Arg&& arg){
    // ...
}

关于c++ - 模板化成员函数和参数转发,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39453180/

相关文章:

c++ - Qt - 如何使用 QFile::copy 使用 QFileDialog 复制文件?

c++ - C++中定义上下文和实例化点之间非依赖构造的解释差异

c++ - 模板模板函数的重载

C++ 模板定义在 clang 上失败,适用于 GCC

c++ - 如何在非泛型上实现完美转发?

c++ - 使用 std::forward 进行参数包扩展的 '...' 的语法

c++ - 为什么 std::forward 会丢弃 constexpr-ness?

c++ - 为什么我在第一个代码中出现段错误,但在第二个代码中却没有?

c++ - gmp 使用 mpz_pow 函数给出错误

c++ - 为什么 std::for_each 是非修改序列操作?