将参数与其他参数一起转发给构造函数

时间:2018-07-31 21:19:15

标签: c++ compiler-errors perfect-forwarding

我正在尝试执行以下操作:

template<typename T, typename Handle, typename... Args>
bool MyClass::CreateArray(T *&array_, Handle *&handle_, const std::string& 
                          handleName_, int64_t size_, int64_t startID_,Args... args)
{
   array_ = ns::makearray<T>(_segment,size_,CACHELINE_SIZE, startID_, std::forward<Args>(args)...);
   handle_ = ns::construct<Handle>(array_);

}

namespace ns {

template<typename T, typename... Args>
T *makearray(mem &segment, size_t size, size_t alignment, int64_t startID, Args... args )
{
    void* ptr = segment.alloc(sizeof(T) * size, alignment);

    //verify alignment
    assert((static_cast<char*>(ptr)-static_cast<char*>(0)) % alignment == 0);

    T* tPtr = static_cast<T*>(ptr);
    T* itr = tPtr;

    for(int64_t i=0; i< size; ++i)
    {
        T* obj = startID ? new (itr) T(i+startingID, std::forward<Args>(args)...)
                         : new (itr) T(std::forward<Args>(args)...);
        ++itr;
    }
    return tPtr;
}
}

使用:

CreateArray<Widget,WidgetHandle>(_array,_arrayHandle,_arrayname,_size,_startingId,_widgettype);
//startingID is int64_t and widgettype is int32_t

class Widget
{
  public:

     Widget::Widget(int64_t id, int32_t type)
     {
        ...
     }
};

我遇到以下编译器错误:

  

错误:没有匹配的函数可以调用ns :: Widget :: Widget(int)

         T* obj = startID ? new (itr) T(i+startingID, std::forward<Args>(args)...)

它与我的2 arg构造函数不匹配。似乎正在忽略(i+startingID)。 您不能在转发时添加其他参数吗?

1 个答案:

答案 0 :(得分:1)

您的代码不完整。这迫使我们对代码的缺失部分做出假设。

  T* obj = startID ? new (itr) T(i+startingID, std::forward<Args>(args)...)
                         : new (itr) T(std::forward<Args>(args)...);

假设args...widgettype,而TWidget,则代码在替换为以下内容后会扩展:

new (itr) Widget(i + startingID, widgettype)

new (itr) Widget(widgettype)

要使代码有效,则Widget(i + startingID, widgettype)Widget(widgettype)都必须有效。您只显示一个Widget::Widget(int64_t id, int32_t type) ctor。如果您没有ctor接受int32_t参数,则该代码无效。

这是错误消息告诉您的内容:

  

没有匹配功能可调用ns :: Widget :: Widget(int)

您可能会感到困惑,因为错误消息可能位于包含错误的完整表达式的开头-赋值的第一行,但实际上它来自第二行new (itr) T(std::forward<Args>(args)...);这是有根据的猜测,因为您尚未提供MCVE。