簡體   English   中英

為什么模板化的非const參數構造函數比給定的復制構造函數更可取

[英]why templated non const parameter constructor is preferred to given copy constructor

我想讓我的課程可以在std::variant

應該起作用的簡單代碼是:

int main()
{
    std::variant< int, A > v;

    A a(1);
    v = a;
}

我的課程包含一個模板化的構造函數:

 template <typename T> A( T& );

此時麻煩開始了! 構造函數綁定到來自std::variant的調用,不再使用提供的A(const A&)

由於復制和粘貼的原因,此處的完整示例為:

#include <iostream>
#include <variant>

class A
{
    private:
        int x;

    public:

        A( A&&) {}
        A( const A& ) {}
        A(){}
        ~A() {}

        A& operator=( const A& ) { return *this;}
        A& operator=( A&& ) {return *this;}

        template <typename T>
            A( T& t  ) 
            {
                std::cout << __PRETTY_FUNCTION__ << std::endl;
            }

        A(int _x):x{_x}{}
};

int main()
{
    std::variant< int, A > v;

    A a(1);
    v = a;
}

背景:

為什么在這里使用模板? 使用使用序列化程序類型的構造函數時,問題開始。 序列化器可以有多種類型,取決於要序列化的文件或流。

備注:我知道構造函數的功能缺失!

問題不在於std::variant 問題在於構造器模板,

template <typename T>
A(T& t)

這樣的構造函數是有問題的,因為當參數是類型A的非const左值時,此構造函數優於采用const A& -的副本構造const A&這通常不是預期的行為。 為了防止這種情況,我們通常用SFINAE約束此構造函數:

template <typename T, typename = std::enable_if_t<!std::is_same_v<std::decay_t<T>, A>>>
A(T& t)  // or T&& t

並可能考慮將其explicit

我們通常不提供拷貝構造函數以非const A&因為它們旁邊多余的那些服用const A&

暫無
暫無

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

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