Variant fails with private default constructor

オープン
#103 コメント 0 件 リアクション 1 件 担当者 0 名 GitHub で見る

まだ誰も着手していません。

評価

難易度
3/5
見積もり時間
1〜2日
初心者へのやさしさ
45/100
issue の種類
バグ
明瞭さ
おおむね明確
活発さ
停滞
技術スタック
cpp
領域
backend

調査の方向性

issue に記載された最小の例とコンパイラのバージョンから始め、次に boost/variant/variant.hpp の find_fallback_type 付近と boost/type_traits/has_nothrow_constructor.hpp を調べます。失敗を確認し、Boost.Variant2 と動作を比較します。完了の条件は、影響を受ける GCC バージョンで、既存の fallback の動作を壊すことなく、private なデフォルトコンストラクタを持つ例がコンパイルできることです。

索引モデルが issue の本文から書いたものです。

説明

Boost.Variant fails if its types have a private default constructor, using gcc 12.2
Minimal example: https://godbolt.org/z/cG4PnW8ee

#include <boost/variant.hpp>
#include <boost/variant2.hpp>
class Foo
{
    public:
        Foo(int a_) : a(a_) {}
        int a;
    private:
        Foo();
};
struct Voo
{
    Foo f;
    double d;
};
struct Doo
{
    Foo f;
    int s;
};
#ifndef USE_VARIANT2
    using VooDoo = boost::variant<Voo, Doo>;
    void testVooDoo(const VooDoo& voodoo)
    {
        VooDoo v{Voo{Foo(3)}};
    } 
#else
    using VooDoo = boost::variant2::variant<Voo, Doo>;
    void testVooDoo(const VooDoo& voodoo)
    {
        VooDoo v{Voo{Foo(3)}};
    }
#endif

If I change to use Boost.Variant2, it works.
If I go back to gcc 7.5, it works (fails after that version).

The error shows:

/opt/compiler-explorer/libs/boost_1_80_0/boost/variant/variant.hpp:194:17:   required from 'struct boost::detail::variant::find_fallback_type<boost::mpl::l_item<mpl_::long_<2>, Voo, boost::mpl::l_item<mpl_::long_<1>, Doo, boost::mpl::l_end> > >'
/opt/compiler-explorer/libs/boost_1_80_0/boost/variant/variant.hpp:1252:17:   required from 'class boost::variant<Voo, Doo>'
<source>:26:16:   required from here
/opt/compiler-explorer/libs/boost_1_80_0/boost/type_traits/has_nothrow_constructor.hpp:27:84: error: 'Foo::Foo()' is private within this context
   27 | template <class T> struct has_nothrow_constructor : public integral_constant<bool, BOOST_HAS_NOTHROW_CONSTRUCTOR(T)>{};
      |                                                                                    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<source>:9:9: note: declared private here
    9 |         Foo();
      |         ^~~

It mentions find_fallback_type, so I guess that at some point it tries to determine the "fallback type" to default construct the VooDoo.
However, nowhere in my program I need to default construct a VooDoo, so I'm not sure why that type needs to be "computed".

Also, somehow Boost.Variant2 doesn't fail, so there must be a way to make this work.

主要言語
C++
スター
47
フォーク
72
PR マージ指標
30日以内にマージされた PR はありません

環境構築

このプロジェクトには開発コンテナ、Dockerfile、コントリビューションガイドがありません。まず README を読み、一般的な手順ははじめてのコントリビューションガイドを参照してください。

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

boostorg/variant のほかの issue

boostorg/variant の issue をすべて見る

似ている issue

C++ の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。