3

次の最小限の例は、次のようにコンパイルされg++ -std=c++11 -Wall tuple.cpp -o tupleます。

#include <tuple>
#include <iostream>

template<int i>
char get_elem_i(std::tuple<char, char> t)
{
    return std::get<i>(t);
}

int main()
{
    std::tuple<char, char> t('H','i');
    char c = get_elem_i<0>(t);
    std::cout << "The char is: " << c << std::endl;
}

現在、インデックスを指定するテンプレートを使用したくありません (正確な理由: 自動的に推定されるテンプレートがあり、それらすべてを指定する必要はありません)。だから私の最初の試みは:

char get_elem_i(int i, std::tuple<char, char> t)
{
    return std::get<i>(t);
}

これはコンパイルできないことを理解しています。iコンパイル時に認識されるコンパイラを保証する方法はありますか? たぶん、このようなものですか?

char get_elem_i(compile_time_known int i, std::tuple<char, char> t)
4

2 に答える 2

1

iコンパイル時にの値を知ることができればi、 のロジックiconstexpr.

例えば:

#include <tuple>
#include <iostream>

constexpr int compile_time_known_i(int input) { return input / 3; }

template<int i>
char get_elem_i(std::tuple<char, char> t)
{
    return std::get<i>(t);
}

int main()
{
    std::tuple<char, char> t('H','i');
    char c = get_elem_i<0>(t);
    char d = get_elem_i<compile_time_known_i(3)>(t);
    std::cout << "The char is: " << c << " " << d <<  std::endl;
}

コンパイル時にあなたiの を知ることができるとすれば、これは物事をきれいにするのに役立つかもしれません (ただし、これがどれだけ意味があるかは、ユースケースによって異なります)。

それがあなたが求めているパラメータを渡す構文である場合、プリプロセッサを使用してこれを実現できます-オプションのtype_traits安全性があります。

#include <tuple>
#include <iostream>
#include <type_traits>

#define get_elem_i_ct(i, t)                                                                \
    std::get<i>(t);                                                                        \
    static_assert(std::is_integral<decltype(i)>::value, #i " must be an integral type");   \
    static_assert(std::is_same<decltype(t), std::tuple<char, char>>::value, #t " must be a tuple");

int main()
{
    std::tuple<char, char> t('H','i');
    char c = get_elem_i_ct(0, t)
    char d = get_elem_i_ct(1, t)
    std::cout << "The char is: " << c << " " << d <<  std::endl;
}

これは述べられた構文要件を達成しますが、このアプローチを怒って使用することはお勧めしません.実際の問題に対するより良い解決策がほぼ確実にあります.

于 2013-05-07T17:43:24.087 に答える