簡體   English   中英

通過模板化的Friend類完美轉發到私有類構造函數

[英]Perfect Forwarding to a Private Class Constructor Through a Templated Friend Class

我正在探索可變參數模板,完美轉發和私有構造函數中對friend關鍵字的使用。 我覺得我缺少所有這些基本知識,因為下面的簡單示例無法編譯。

我希望Test_Manager<Test_Class>::Process是構造類型為Test_Class的對象的唯一方法( Process最終會做更多的事情,但這是一個簡單的示例)。 我還希望Test_Manager能夠以這種方式“管理”各種類,因此類類型的參數t_Symbol以及可變的...t_Args可以處理各種構造函數。

// Test.cpp
#include <string>

template<typename t_Symbol>
struct Test_Manager
{
    template<typename... t_Args>
    static t_Symbol Process(const t_Args&... i_Args)
    {
        const t_Symbol New_Symbol(std::forward<t_Args>(i_Args)...); // error C2665

        return New_Symbol;
    }
};

class Test_Class
{
    private:

        friend Test_Manager<Test_Class>;

        Test_Class() {};
        Test_Class(const std::string& i_Text) : m_Text(i_Text) {};

        const std::string m_Text;
};

void Test_Function()
{
    std::string text = "hello_world";

    Test_Class t = Test_Manager<Test_Class>::Process(text);
}

但是,在Visual Studio 2015 Update 3中,出現以下錯誤(在上面標記的行): error C2665: 'std::forward': none of the 2 overloads could convert all the argument types 我在這里搞砸了嗎? 我覺得這應該工作。

我在這里搞砸了嗎?

是的,你是。 在下面的代碼中:

template<typename... t_Args>
static t_Symbol Process(const t_Args&... i_Args){
    const t_Symbol New_Symbol(std::forward<t_Args>(i_Args)...);
    ...
}

上面的問題是i_Args將具有const限定符,但是您告訴std::forward std::forward<t_Arg>您將發送一個不包含const限定符的t_Arg類型。

因此,從本質std::forward<t_Args>(i_Arg) ,您的std::forward<t_Args>(i_Arg)的問題在於類型 t_Args不帶有隱式const ,但是參數 i_Arg具有const

您應該在轉發引用上使用std::forward 當您這樣做時, t_Arg將隱式攜帶必要的cv限定條件,該條件將與i_Argcv限定條件匹配

您想要將其更改為:

template<typename... t_Args>
static t_Symbol Process(t_Args&&... i_Args){
    ...
}

編輯,根據Guillaume Racicot的評論:

當您嘗試移動Process ,例如:

Test_Manager<Test_Class>::Process(std::move(text));

Test_Class的構造Test_Class將擊敗std::forward因為它仍將按照每個副本進行復制。

Test_Class(const std::string& i_Text) : m_Text(i_Text) {};

但是,當構造函數定義為:

Test_Class(std::string i_Text) : m_Text(std::move(i_Text)) {};

不會復制,只能移動。

std::forward旨在與轉發引用(或通用引用)一起使用,轉發引用是T&&函數參數,其中T是模板參數。 完美的轉發如下所示:

template<typename... t_Args>
static t_Symbol Process(t_Args&&... i_Args)
{
    t_Symbol New_Symbol(std::forward<t_Args>(i_Args)...);

    return New_Symbol;
}

如果您希望Process只采用const左值,那是可以的,但是不要使用std::forward

template<typename... t_Args>
static t_Symbol Process(const t_Args&... i_Args)
{
    t_Symbol New_Symbol(i_Args...);

    return New_Symbol;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM