C ++で列挙型を使用して関数の戻り値の型を特殊化するにはどうすればよいですか?

お粗末

バリアントを使用して、C ++の構文パーサーのさまざまな型を格納しています。構文ルールの各構成要素には、(列挙型の)カテゴリと値があります。構成要素は、カテゴリに応じて値のタイプを格納します。例として、カテゴリを「文字列」=>文字列を格納し、「数値」=>整数を格納するように簡略化しました。

カテゴリ列挙型に従って正しいタイプの構成要素の値を取得したいと思います。これどうやってするの?

以下にサンプルコードを記述しました。ここでは、文字列を格納するstrConとintを格納するintConの2つの構成要素を作成し、それらの値を取得しようとしています。

strConの文字列をstrValに割り当て、intをintConからintValに割り当てたいと思います。

#include <variant>

struct Constituent
{
    enum class Category {String, Number};
    using Value = std::variant<std::string, int>;

    Category cat;
    Value val;

    // Using a struct ideally to allow partial specialisation of the template,
    // so I can pass the enum without the return type.
    template<Category T>
    struct OfCategory {};

    template<Category T, typename U>
    friend U const& getValue(OfCategory<T>, Constituent const&);
}

using Category = Constituent::Category;

// Template to return the value as the correct type
// for the constituent's category.
template<Category T, typename U>
U const& getValue(OfCategory<T> type, Constituent const& constituent)
{
    // Uses the variant's get function.
    return std::get<U>(constituent.val);
}

// Specialisation to return string from Category::String.
template<>
string const& getValue(OfCategory<Category::String> type,
    Constituent const& constituent)
{
    return getValue<Category::String, string>(constituent);
}

// Specialisation to return int from Category::Number.
template<>
int const& getValue(OfCategory<Category::Number> type,
    Constituent const& constituent)
{
    return getValue<Category::Number, int>(constituent);
}

int main()
{
    Constituent strCon = {Category::String, "This is a string!"};
    Constituent intCon = {Category::Number, 20};

    // In my current implementation, I want this to work with
    // the type wrapper as an overload for the function.
    string strVal = getValue(OfCategory<Category::String>{}, strCon);
    int intVal = getValue(OfCategory<Category::Number>{}, intCon);

    // But it would be better to directly use the template.
    strVal = getValue<Category::String>(strCon);
    intVal = getValue<Category::Number>(intCon);

    // The only way I can get it to work, is to explicitly provide
    // the return type, which defeats the point.
    strVal = getValue<Category::String, string>(
        OfCategory<Category::String>{}, strCon);
    intVal = getValue<Category::Number, int>(
        OfCategory<Category::Number>{}, intCon);

    // Ideally, I could use the cat parameter in Constituent to dynamically
    // infer the return type, but I don't believe something like this is
    // possible in C++.
}
Jarod42

列挙型からタイプを提供するには、いくつかの特性を追加する必要があります。たとえば、次のように再利用しOfCategoryます。

template<Category T> struct OfCategory;

template<> struct OfCategory<Category::String> { using type = std::string; };
template<> struct OfCategory<Category::Number> { using type = int; };

次に、追加の専門分野を必要とせずに:

template <Category T>
const typename OfCategory<T>::type&
getValue(OfCategory<T> type, Constituent const& constituent)
{
    // Uses the variant's get function.
    return std::get<typename OfCategory<T>::type>(constituent.val);
}

次のような呼び出しの場合:getValue(OfCategory<Category::String>{}, strCon)

あるいは:

template <Category T>
const typename OfCategory<T>::type&
getValue(Constituent const& constituent)
{
    // Uses the variant's get function.
    return std::get<typename OfCategory<T>::type>(constituent.val);
}

のような呼び出しのために getValue<Category::String>(strCon);

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

分類Dev

C ++ 11では、戻り値の型に基づいて関数オブジェクトを受け取る関数テンプレートを特殊化するにはどうすればよいですか?

分類Dev

このC ++の例で列挙型を正しく使用するにはどうすればよいですか?

分類Dev

C#で列挙型を使用してコードの繰り返しを回避するにはどうすればよいですか?

分類Dev

将来の特殊化のために、C ++テンプレート関数を戻り値の型に依存しないようにする方法

分類Dev

C ++で列挙型をフラグとして使用するにはどうすればよいですか?

分類Dev

値からC#列挙型の説明を取得するにはどうすればよいですか?

分類Dev

Boostを使用してC ++ 14スタイルの自動戻り値型を実現するにはどうすればよいですか?

分類Dev

Boostを使用してC ++ 14スタイルの自動戻り値型を実現するにはどうすればよいですか?

分類Dev

C ++でラムダ関数の戻り値の型を比較するにはどうすればよいですか?

分類Dev

この列挙型をObjective-Cで使用するにはどうすればよいですか?

分類Dev

変数varをC#の列挙型と比較するにはどうすればよいですか?

分類Dev

C ++ 14で自動戻り値の型を使用して明示的なテンプレートの特殊化を行うことは有効ですか?

分類Dev

C ++の型特性を使用して関数の引数の型を取得するにはどうすればよいですか?

分類Dev

cの関数の戻り値のみを取得するにはどうすればよいですか?

分類Dev

列挙型のQlistをC ++からQMLに公開するにはどうすればよいですか?

分類Dev

C ++ 11 int値で列挙型クラス値を取得するにはどうすればよいですか?

分類Dev

C ++:関数の戻り値の精度を設定するにはどうすればよいですか?

分類Dev

列挙型をC#のリストに変換するにはどうすればよいですか?

分類Dev

Pythonで複素数型のC関数を使用するにはどうすればよいですか?

分類Dev

(C#)Mono.Cecilを使用して列挙型であるかどうかを判断するにはどうすればよいですか?

分類Dev

C ++で割り当てられた列挙型からランダムな値を取得するにはどうすればよいですか?

分類Dev

C#で列挙型を適切に切り替えるにはどうすればよいですか?

分類Dev

Cで列挙型を安全に使用するにはどうすればよいですか?

分類Dev

入力C ++に応じて戻り値の型を変更するにはどうすればよいですか?

分類Dev

maxValueをdecimal型のDataTable列に割り当てるにはどうすればよいですか?(C#)

分類Dev

Asp.Net Core DropdownListを取得して[Display()]値をC#列挙型で表示するにはどうすればよいですか?

分類Dev

関数を使用してcの数値を読み取り、それをmainで使用するにはどうすればよいですか?

分類Dev

整数を値として含むC#列挙型を定義するにはどうすればよいですか?

分類Dev

C ++とインターフェイスするためにRustで列挙型の表現型を指定するにはどうすればよいですか?

Related 関連記事

  1. 1

    C ++ 11では、戻り値の型に基づいて関数オブジェクトを受け取る関数テンプレートを特殊化するにはどうすればよいですか?

  2. 2

    このC ++の例で列挙型を正しく使用するにはどうすればよいですか?

  3. 3

    C#で列挙型を使用してコードの繰り返しを回避するにはどうすればよいですか?

  4. 4

    将来の特殊化のために、C ++テンプレート関数を戻り値の型に依存しないようにする方法

  5. 5

    C ++で列挙型をフラグとして使用するにはどうすればよいですか?

  6. 6

    値からC#列挙型の説明を取得するにはどうすればよいですか?

  7. 7

    Boostを使用してC ++ 14スタイルの自動戻り値型を実現するにはどうすればよいですか?

  8. 8

    Boostを使用してC ++ 14スタイルの自動戻り値型を実現するにはどうすればよいですか?

  9. 9

    C ++でラムダ関数の戻り値の型を比較するにはどうすればよいですか?

  10. 10

    この列挙型をObjective-Cで使用するにはどうすればよいですか?

  11. 11

    変数varをC#の列挙型と比較するにはどうすればよいですか?

  12. 12

    C ++ 14で自動戻り値の型を使用して明示的なテンプレートの特殊化を行うことは有効ですか?

  13. 13

    C ++の型特性を使用して関数の引数の型を取得するにはどうすればよいですか?

  14. 14

    cの関数の戻り値のみを取得するにはどうすればよいですか?

  15. 15

    列挙型のQlistをC ++からQMLに公開するにはどうすればよいですか?

  16. 16

    C ++ 11 int値で列挙型クラス値を取得するにはどうすればよいですか?

  17. 17

    C ++:関数の戻り値の精度を設定するにはどうすればよいですか?

  18. 18

    列挙型をC#のリストに変換するにはどうすればよいですか?

  19. 19

    Pythonで複素数型のC関数を使用するにはどうすればよいですか?

  20. 20

    (C#)Mono.Cecilを使用して列挙型であるかどうかを判断するにはどうすればよいですか?

  21. 21

    C ++で割り当てられた列挙型からランダムな値を取得するにはどうすればよいですか?

  22. 22

    C#で列挙型を適切に切り替えるにはどうすればよいですか?

  23. 23

    Cで列挙型を安全に使用するにはどうすればよいですか?

  24. 24

    入力C ++に応じて戻り値の型を変更するにはどうすればよいですか?

  25. 25

    maxValueをdecimal型のDataTable列に割り当てるにはどうすればよいですか?(C#)

  26. 26

    Asp.Net Core DropdownListを取得して[Display()]値をC#列挙型で表示するにはどうすればよいですか?

  27. 27

    関数を使用してcの数値を読み取り、それをmainで使用するにはどうすればよいですか?

  28. 28

    整数を値として含むC#列挙型を定義するにはどうすればよいですか?

  29. 29

    C ++とインターフェイスするためにRustで列挙型の表現型を指定するにはどうすればよいですか?

ホットタグ

アーカイブ