簡體   English   中英

在轉換為std :: optional時,Clang和GCC的結果不同<T>

[英]Different results in Clang and GCC when casting to std::optional<T>

給出以下代碼:

#include <iostream>
#include <optional>

struct foo
{
    explicit operator std::optional<int>() {
        return std::optional<int>( 1 );
    }
    explicit operator int() {
        return 0;
    }
};

int main()
{
    foo my_foo;
    std::optional<int> my_opt( my_foo );
    std::cout << "value: " << my_opt.value() << std::endl;
}

gcc 7.2.0寫入 value: 1

MSVC 2017(15.3)和clang 4.0.0但寫入 value: 0

根據C ++標准,哪一個是正確的?

由於這是直接初始化,我們枚舉構造函數並選擇最佳構造函數 std::optional的相關構造函數是:

constexpr optional( const optional& other ); // (2)
constexpr optional( optional&& other ) noexcept(/* see below */); // (3)

template < class U = value_type >
/* EXPLICIT */ constexpr optional( U&& value ); // (8), with U = foo&

兩者都是可行的( (8)只參與重載解析,如果int可以從foo&構造而且foo既不是std::in_place_t也不是std::optional<int> ,所有這些都保持),但是(8)是精確匹配而(2)(3)需要用戶定義的轉換,因此應該首選。 gcc在這里錯了。

但是,gcc實際上也沒有調用(3) 它只是直接從my_foo轉換為optional<int>的結果初始化my_opt 這個程序與gcc 7.2打印3但沒有1a1b2

#include <iostream>

template <class T>
struct opt {
    opt() { }
    opt(opt const& ) { std::cout << "1a\n"; }
    opt(opt&& ) { std::cout << "1b\n"; }

    template <class U>
    opt(U&& ) { std::cout << "2\n"; }
};

struct foo 
{
    explicit operator opt<int>() { std::cout << "3\n"; return {}; }
};

int main()
{
    opt<int> o(foo{});
}

我不認為這是一條允許的路線。 我提交了81952

暫無
暫無

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

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