型の特性を使用して、std::array
または普通の古いCスタイルの配列の要素型を取得したいとします。 std::array<char, 3>
またはchar[3]
のいずれかを指定すると、char
が返されます。これを行うにはstd :: arrayまたはCスタイルの配列の要素型を取得するtrait型
メカニズムは、私は、プレーンアレイ上std::array
上::value_type
、およびstd::remove_all_extents
を使用することができます...部分的にしか場所であるように見えるが、私は、私は」の両方を兼ね備えたシングルタイプの形質を見つけることができません自分で書くことができません。
私は、この限りで持っている:
#include <array>
#include <type_traits>
template <class T>
using element_type = typename std::conditional<
std::is_array<T>::value,
typename std::remove_all_extents<T>::type,
typename T::value_type
>::type;
もちろん、std::array
のためだけで正常に動作:
int main()
{
static_assert(
std::is_same<char, element_type<std::array<char, 3>>>::value,
"element_type failed");
}
が、休憩が、私はそれをプレーンな配列を渡し、明らかに平野理由配列には::value_type
が含まれていません。 、あなたが期待するよう:「に続いたときに 『::』をクラスまたは名前空間でなければならない『T』」
static_assert(std::is_same<char, element_type<char[3]>>::value, "element_type failed");
だけのようなエラーが発生します。
私が関数を書いていたのであれば、std::enable_if
を使って問題のテンプレートのインスタンス化を隠していましたが、このアプローチを型の特性でどのように使うことができません。
この問題を解決する正しい方法は何ですか?
私はあなたが' std :: begin'。 – Rook
少し改善することができます。範囲ベースのforは 'begin/end'関数を見つけるが、このエイリアステンプレートは見つからないコーナーケースがいくつかあります。 'auto begin_adl_helper(T && t){namespace stdを使って関数を定義する; return begin(t);} 'この関数を使用するようにエイリアスを変更します。次に、std以外の名前空間で 'begin'をオーバーロードする型もうまくいきます。 – SirGuy
@SirGuy本当に?私はいつも、使用のために内部的に開始と終了があると考えました。あなたは例を挙げることができますか? – Rakete1111