diff --git a/docs/source/Schemas.md b/docs/source/Schemas.md
index 322ec4f204644773674204d17199eea6326389bd..c4a942166b042a67f00a3ac45e22a11b33c743cb 100755
--- a/docs/source/Schemas.md
+++ b/docs/source/Schemas.md
@@ -158,6 +158,10 @@ If you have a need to distinguish between different FlatBuffers in a more
 open-ended way, for example for use as files, see the file identification
 feature below.
 
+There is an experimental support only in C++ for a vector of unions
+(and types). In the example IDL file above, use [Any] to add a
+vector of Any to Monster table.
+
 ### Namespaces
 
 These will generate the corresponding namespace in C++ for all helper
diff --git a/include/flatbuffers/idl.h b/include/flatbuffers/idl.h
index ad90d53589df2f493cce1078321f54b7eeb1c247..aab4b8fa64580844aa5106173ea89fd544694447 100644
--- a/include/flatbuffers/idl.h
+++ b/include/flatbuffers/idl.h
@@ -356,10 +356,25 @@ struct IDLOptions {
   bool allow_non_utf8;
 
   // Possible options for the more general generator below.
-  enum Language { kJava, kCSharp, kGo, kMAX };
+  enum Language {
+    kJava   = 1 << 0,
+    kCSharp = 1 << 1,
+    kGo     = 1 << 2,
+    kCpp    = 1 << 3,
+    kJs     = 1 << 4,
+    kPython = 1 << 5,
+    kPhp    = 1 << 6,
+    kJson   = 1 << 7,
+    kBinary = 1 << 8,
+    kMAX
+  };
 
   Language lang;
 
+  // The corresponding language bit will be set if a language is included
+  // for code generation.
+  unsigned long lang_to_generate;
+
   IDLOptions()
     : strict_json(false),
       skip_js_exports(false),
@@ -378,7 +393,8 @@ struct IDLOptions {
       cpp_object_api_pointer_type("std::unique_ptr"),
       union_value_namespacing(true),
       allow_non_utf8(false),
-      lang(IDLOptions::kJava) {}
+      lang(IDLOptions::kJava),
+      lang_to_generate(0) {}
 };
 
 // This encapsulates where the parser is in the current source file.
diff --git a/samples/monster_generated.h b/samples/monster_generated.h
index 3c86e87a4a0b508c3ed3985f49bcd717f6b0ec4e..0cf21f7bce9c19a14d687edded56db35f2527538 100644
--- a/samples/monster_generated.h
+++ b/samples/monster_generated.h
@@ -99,6 +99,7 @@ struct EquipmentUnion {
 };
 
 bool VerifyEquipment(flatbuffers::Verifier &verifier, const void *obj, Equipment type);
+bool VerifyEquipmentVector(flatbuffers::Verifier &verifier, const flatbuffers::Vector<flatbuffers::Offset<void>> *values, const flatbuffers::Vector<uint8_t> *types);
 
 MANUALLY_ALIGNED_STRUCT(4) Vec3 FLATBUFFERS_FINAL_CLASS {
  private:
@@ -510,6 +511,17 @@ inline bool VerifyEquipment(flatbuffers::Verifier &verifier, const void *obj, Eq
   }
 }
 
+inline bool VerifyEquipmentVector(flatbuffers::Verifier &verifier, const flatbuffers::Vector<flatbuffers::Offset<void>> *values, const flatbuffers::Vector<uint8_t> *types) {
+  if (values->size() != types->size()) return false;
+  for (flatbuffers::uoffset_t i = 0; i < values->size(); ++i) {
+    if (!VerifyEquipment(
+        verifier,  values->Get(i), types->GetEnum<Equipment>(i))) { 
+      return false; 
+    }
+  }
+  return true;
+}
+
 inline flatbuffers::NativeTable *EquipmentUnion::UnPack(const void *obj, Equipment type, const flatbuffers::resolver_function_t *resolver) {
   switch (type) {
     case Equipment_Weapon: {
diff --git a/src/flatc.cpp b/src/flatc.cpp
index 7fc04012f554b00a823f37864396e158ea450353..f5553e85fea644ed95fcbc74f68bab77017d33a9 100644
--- a/src/flatc.cpp
+++ b/src/flatc.cpp
@@ -47,17 +47,17 @@ struct Generator {
 const Generator generators[] = {
   { flatbuffers::GenerateBinary,   "-b", "--binary", "binary",
     nullptr,
-    flatbuffers::IDLOptions::kMAX,
+    flatbuffers::IDLOptions::kBinary,
     "Generate wire format binaries for any data definitions",
     flatbuffers::BinaryMakeRule },
   { flatbuffers::GenerateTextFile, "-t", "--json", "text",
     nullptr,
-    flatbuffers::IDLOptions::kMAX,
+    flatbuffers::IDLOptions::kJson,
     "Generate text output for any data definitions",
     flatbuffers::TextMakeRule },
   { flatbuffers::GenerateCPP,      "-c", "--cpp", "C++",
     flatbuffers::GenerateCppGRPC,
-    flatbuffers::IDLOptions::kMAX,
+    flatbuffers::IDLOptions::kCpp,
     "Generate C++ headers for tables/structs",
     flatbuffers::CPPMakeRule },
   { flatbuffers::GenerateGo,       "-g", "--go", "Go",
@@ -72,7 +72,7 @@ const Generator generators[] = {
     flatbuffers::GeneralMakeRule },
   { flatbuffers::GenerateJS,       "-s", "--js", "JavaScript",
     nullptr,
-    flatbuffers::IDLOptions::kMAX,
+    flatbuffers::IDLOptions::kJs,
     "Generate JavaScript code for tables/structs",
     flatbuffers::JSMakeRule },
   { flatbuffers::GenerateGeneral,  "-n", "--csharp", "C#",
@@ -82,12 +82,12 @@ const Generator generators[] = {
     flatbuffers::GeneralMakeRule },
   { flatbuffers::GeneratePython,   "-p", "--python", "Python",
     nullptr,
-    flatbuffers::IDLOptions::kMAX,
+    flatbuffers::IDLOptions::kPython,
     "Generate Python files for tables/structs",
     flatbuffers::GeneralMakeRule },
   { flatbuffers::GeneratePhp, nullptr, "--php", "PHP",
     nullptr,
-    flatbuffers::IDLOptions::kMAX,
+    flatbuffers::IDLOptions::kPhp,
     "Generate PHP files for tables/structs",
     flatbuffers::GeneralMakeRule },
 };
@@ -267,6 +267,7 @@ int main(int argc, const char *argv[]) {
                arg == generators[i].generator_opt_short)) {
             generator_enabled[i] = true;
             any_generator = true;
+            opts.lang_to_generate |= generators[i].lang;
             goto found;
           }
         }
diff --git a/src/idl_gen_cpp.cpp b/src/idl_gen_cpp.cpp
index 6696438b547c0ac40dc01061180bb95ef5cf00d2..c8acb1fd4a37e71449fa3dc2b2abb78d54ecd1fb 100644
--- a/src/idl_gen_cpp.cpp
+++ b/src/idl_gen_cpp.cpp
@@ -454,6 +454,13 @@ class CppGenerator : public BaseGenerator {
            enum_def.name + " type)";
   }
 
+  static std::string UnionVectorVerifySignature(const EnumDef &enum_def) {
+    return "bool Verify" + enum_def.name + "Vector" +
+           "(flatbuffers::Verifier &verifier, " +
+           "const flatbuffers::Vector<flatbuffers::Offset<void>> *values, " +
+           "const flatbuffers::Vector<uint8_t> *types)";
+  }
+
   static std::string UnionUnPackSignature(const EnumDef &enum_def,
                                           bool inclass) {
     return (inclass ? "static " : "") +
@@ -685,6 +692,7 @@ class CppGenerator : public BaseGenerator {
 
     if (enum_def.is_union) {
       code_ += UnionVerifySignature(enum_def) + ";";
+      code_ += UnionVectorVerifySignature(enum_def) + ";";
       code_ += "";
     }
   }
@@ -721,6 +729,18 @@ class CppGenerator : public BaseGenerator {
     code_ += "}";
     code_ += "";
 
+    code_ += "inline " + UnionVectorVerifySignature(enum_def) + " {";
+    code_ += "  if (values->size() != types->size()) return false;";
+    code_ += "  for (flatbuffers::uoffset_t i = 0; i < values->size(); ++i) {";
+    code_ += "    if (!Verify" + enum_def.name + "(";
+    code_ += "        verifier,  values->Get(i), types->GetEnum<" + enum_def.name + ">(i))) { ";
+    code_ += "      return false; ";
+    code_ += "    }";
+    code_ += "  }";
+    code_ += "  return true;";
+    code_ += "}";
+    code_ += "";
+
     if (parser_.opts.generate_object_based_api) {
       // Generate union Unpack() and Pack() functions.
       code_ += "inline " + UnionUnPackSignature(enum_def, false) + " {";
@@ -995,6 +1015,10 @@ class CppGenerator : public BaseGenerator {
             }
             break;
           }
+          case BASE_TYPE_UNION: {
+            code_ += "{{PRE}}Verify{{ENUM_NAME}}Vector(verifier, {{NAME}}(), {{NAME}}_type())\\";
+            break;
+          }
           default:
             break;
         }
diff --git a/src/idl_gen_general.cpp b/src/idl_gen_general.cpp
index 8c3220785f241714dbb7706ff9c039f92a836284..857bf46c871284f64beade33fc03f4d106fbaa3b 100644
--- a/src/idl_gen_general.cpp
+++ b/src/idl_gen_general.cpp
@@ -70,108 +70,80 @@ struct LanguageParameters {
   CommentConfig comment_config;
 };
 
-LanguageParameters language_parameters[] = {
-  {
-    IDLOptions::kJava,
-    false,
-    ".java",
-    "String",
-    "boolean ",
-    " {\n",
-    "class ",
-    " final ",
-    "final ",
-    "final class ",
-    ";\n",
-    "()",
-    "",
-    " extends ",
-    "package ",
-    ";",
-    "",
-    "_bb.order(ByteOrder.LITTLE_ENDIAN); ",
-    "position()",
-    "offset()",
-    "",
-    "",
-    "",
-    "import java.nio.*;\nimport java.lang.*;\nimport java.util.*;\n"
-      "import com.google.flatbuffers.*;\n\n@SuppressWarnings(\"unused\")\n",
+const LanguageParameters& GetLangParams(IDLOptions::Language lang) {
+  static LanguageParameters language_parameters[] = {
     {
-      "/**",
-      " *",
-      " */",
+      IDLOptions::kJava,
+      false,
+      ".java",
+      "String",
+      "boolean ",
+      " {\n",
+      "class ",
+      " final ",
+      "final ",
+      "final class ",
+      ";\n",
+      "()",
+      "",
+      " extends ",
+      "package ",
+      ";",
+      "",
+      "_bb.order(ByteOrder.LITTLE_ENDIAN); ",
+      "position()",
+      "offset()",
+      "",
+      "",
+      "",
+      "import java.nio.*;\nimport java.lang.*;\nimport java.util.*;\n"
+        "import com.google.flatbuffers.*;\n\n@SuppressWarnings(\"unused\")\n",
+      {
+        "/**",
+        " *",
+        " */",
+      },
     },
-  },
-  {
-    IDLOptions::kCSharp,
-    true,
-    ".cs",
-    "string",
-    "bool ",
-    "\n{\n",
-    "struct ",
-    " readonly ",
-    "",
-    "enum ",
-    ",\n",
-    " { get",
-    "} ",
-    " : ",
-    "namespace ",
-    "\n{",
-    "\n}\n",
-    "",
-    "Position",
-    "Offset",
-    "__p.",
-    "Table.",
-    "?",
-    "using System;\nusing FlatBuffers;\n\n",
     {
-      nullptr,
-      "///",
-      nullptr,
+      IDLOptions::kCSharp,
+      true,
+      ".cs",
+      "string",
+      "bool ",
+      "\n{\n",
+      "struct ",
+      " readonly ",
+      "",
+      "enum ",
+      ",\n",
+      " { get",
+      "} ",
+      " : ",
+      "namespace ",
+      "\n{",
+      "\n}\n",
+      "",
+      "Position",
+      "Offset",
+      "__p.",
+      "Table.",
+      "?",
+      "using System;\nusing FlatBuffers;\n\n",
+      {
+        nullptr,
+        "///",
+        nullptr,
+      },
     },
-  },
-  // TODO: add Go support to the general generator.
-  // WARNING: this is currently only used for generating make rules for Go.
-  {
-    IDLOptions::kGo,
-    true,
-    ".go",
-    "string",
-    "bool ",
-    "\n{\n",
-    "class ",
-    "const ",
-    " ",
-    "class ",
-    ";\n",
-    "()",
-    "",
-    "",
-    "package ",
-    "",
-    "",
-    "",
-    "position()",
-    "offset()",
-    "",
-    "",
-    "",
-    "import (\n\tflatbuffers \"github.com/google/flatbuffers/go\"\n)",
-    {
-      nullptr,
-      "///",
-      nullptr,
-    },
-  }
-};
+  };
 
-static_assert(sizeof(language_parameters) / sizeof(LanguageParameters) ==
-              IDLOptions::kMAX,
-              "Please add extra elements to the arrays above.");
+  if (lang == IDLOptions::kJava) {
+    return language_parameters[0];
+  } else {
+    assert(lang == IDLOptions::kCSharp);
+    return language_parameters[1];
+  }
+}
 
 namespace general {
 class GeneralGenerator : public BaseGenerator {
@@ -179,10 +151,10 @@ class GeneralGenerator : public BaseGenerator {
   GeneralGenerator(const Parser &parser, const std::string &path,
                    const std::string &file_name)
       : BaseGenerator(parser, path, file_name, "", "."),
-        lang_(language_parameters[parser_.opts.lang]),
+        lang_(GetLangParams(parser_.opts.lang)),
         cur_name_space_( nullptr ) {
-    assert(parser_.opts.lang <= IDLOptions::kMAX);
-      };
+  }
+
   GeneralGenerator &operator=(const GeneralGenerator &);
   bool generate() {
     std::string one_file_code;
@@ -258,9 +230,16 @@ static bool IsEnum(const Type& type) {
 }
 
 std::string GenTypeBasic(const Type &type, bool enableLangOverrides) {
-  static const char *gtypename[] = {
+  static const char *java_typename[] = {
     #define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, JTYPE, GTYPE, NTYPE, PTYPE) \
-        #JTYPE, #NTYPE, #GTYPE,
+        #JTYPE,
+      FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD)
+    #undef FLATBUFFERS_TD
+  };
+
+  static const char *csharp_typename[] = {
+    #define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, JTYPE, GTYPE, NTYPE, PTYPE) \
+        #NTYPE,
       FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD)
     #undef FLATBUFFERS_TD
   };
@@ -274,7 +253,12 @@ std::string GenTypeBasic(const Type &type, bool enableLangOverrides) {
     }
   }
 
-  return gtypename[type.base_type * IDLOptions::kMAX + lang_.language];
+  if (lang_.language == IDLOptions::kJava) {
+    return java_typename[type.base_type];
+  } else {
+    assert(lang_.language == IDLOptions::kCSharp);
+    return csharp_typename[type.base_type];
+  }
 }
 
 std::string GenTypeBasic(const Type &type) {
@@ -1352,7 +1336,7 @@ void GenStruct(StructDef &struct_def, std::string *code_ptr) {
   code += (lang_.language != IDLOptions::kJava) ? ";" : "";
   code += "\n\n";
 }
-    const LanguageParameters & lang_;
+    const LanguageParameters& lang_;
     // This tracks the current namespace used to determine if a type need to be prefixed by its namespace
     const Namespace *cur_name_space_;
 };
@@ -1367,7 +1351,7 @@ bool GenerateGeneral(const Parser &parser, const std::string &path,
 std::string GeneralMakeRule(const Parser &parser, const std::string &path,
                             const std::string &file_name) {
   assert(parser.opts.lang <= IDLOptions::kMAX);
-  auto lang = language_parameters[parser.opts.lang];
+  const auto &lang = GetLangParams(parser.opts.lang);
 
   std::string make_rule;
 
diff --git a/src/idl_parser.cpp b/src/idl_parser.cpp
index cb02fc484ed840077f662f9a7a2a1d140117bff9..fa7b98bf5a4e770137c856420d17c369e4fc1223 100644
--- a/src/idl_parser.cpp
+++ b/src/idl_parser.cpp
@@ -554,12 +554,6 @@ CheckedError Parser::ParseType(Type &type) {
         return Error(
               "nested vector types not supported (wrap in table first).");
       }
-      if (subtype.base_type == BASE_TYPE_UNION) {
-        // We could support this if we stored a struct of 2 elements per
-        // union element.
-        return Error(
-              "vector of union types not supported (wrap in table first).");
-      }
       type = Type(BASE_TYPE_VECTOR, subtype.struct_def, subtype.enum_def);
       type.element = subtype.base_type;
       EXPECT(']');
@@ -611,6 +605,19 @@ CheckedError Parser::ParseField(StructDef &struct_def) {
     // with a special suffix.
     ECHECK(AddField(struct_def, name + UnionTypeFieldSuffix(),
                     type.enum_def->underlying_type, &typefield));
+  } else if (type.base_type == BASE_TYPE_VECTOR &&
+             type.element == BASE_TYPE_UNION) {
+    // Only cpp supports the union vector feature so far.
+    if (opts.lang_to_generate != IDLOptions::kCpp) {
+      return Error("Vectors of unions are not yet supported in all "
+                   "the specified programming languages.");
+    }
+    // For vector of union fields, add a second auto-generated vector field to
+    // hold the types, with a special suffix.
+    Type union_vector(BASE_TYPE_VECTOR, nullptr, type.enum_def);
+    union_vector.element = BASE_TYPE_UTYPE;
+    ECHECK(AddField(struct_def, name + UnionTypeFieldSuffix(),
+                    union_vector, &typefield));
   }
 
   FieldDef *field;
diff --git a/tests/generate_code.sh b/tests/generate_code.sh
index bf6f3c8ebf041477447d89e9ad12061d772f0607..0510b01d2b4dee7075d1399220da495b256a49f8 100755
--- a/tests/generate_code.sh
+++ b/tests/generate_code.sh
@@ -16,7 +16,7 @@
 
 ../flatc --cpp --java --csharp --go --binary --python --js --php --grpc --gen-mutable --gen-object-api --no-includes monster_test.fbs monsterdata_test.json
 ../flatc --cpp --java --csharp --go --binary --python --js --php --gen-mutable -o namespace_test namespace_test/namespace_test1.fbs namespace_test/namespace_test2.fbs
-../flatc --binary --schema monster_test.fbs
+../flatc --cpp -o union_vector ./union_vector/union_vector.fbs
 cd ../samples
 ../flatc --cpp --gen-mutable --gen-object-api monster.fbs
 cd ../reflection
diff --git a/tests/monster_test_generated.h b/tests/monster_test_generated.h
index 3fc7cbeec10bc3253a88a361d5f6de41ad3ce38a..b96f85e8550c01c19430aae82e6155a9bb902bc3 100644
--- a/tests/monster_test_generated.h
+++ b/tests/monster_test_generated.h
@@ -136,6 +136,7 @@ struct AnyUnion {
 };
 
 bool VerifyAny(flatbuffers::Verifier &verifier, const void *obj, Any type);
+bool VerifyAnyVector(flatbuffers::Verifier &verifier, const flatbuffers::Vector<flatbuffers::Offset<void>> *values, const flatbuffers::Vector<uint8_t> *types);
 
 MANUALLY_ALIGNED_STRUCT(2) Test FLATBUFFERS_FINAL_CLASS {
  private:
@@ -1198,6 +1199,17 @@ inline bool VerifyAny(flatbuffers::Verifier &verifier, const void *obj, Any type
   }
 }
 
+inline bool VerifyAnyVector(flatbuffers::Verifier &verifier, const flatbuffers::Vector<flatbuffers::Offset<void>> *values, const flatbuffers::Vector<uint8_t> *types) {
+  if (values->size() != types->size()) return false;
+  for (flatbuffers::uoffset_t i = 0; i < values->size(); ++i) {
+    if (!VerifyAny(
+        verifier,  values->Get(i), types->GetEnum<Any>(i))) { 
+      return false; 
+    }
+  }
+  return true;
+}
+
 inline flatbuffers::NativeTable *AnyUnion::UnPack(const void *obj, Any type, const flatbuffers::resolver_function_t *resolver) {
   switch (type) {
     case Any_Monster: {
diff --git a/tests/test.cpp b/tests/test.cpp
index 01d23e0a642a922582957b8294671287c41d027a..02a8b8265307a4d4fbc571bf82edf8929f57c7e0 100644
--- a/tests/test.cpp
+++ b/tests/test.cpp
@@ -21,6 +21,7 @@
 #include "monster_test_generated.h"
 #include "namespace_test/namespace_test1_generated.h"
 #include "namespace_test/namespace_test2_generated.h"
+#include "union_vector/union_vector_generated.h"
 
 #ifndef FLATBUFFERS_CPP98_STL
   #include <random>
@@ -954,7 +955,6 @@ void ErrorTest() {
   TestError("@", "illegal");
   TestError("table 1", "expecting");
   TestError("table X { Y:[[int]]; }", "nested vector");
-  TestError("union Z { X } table X { Y:[Z]; }", "vector of union");
   TestError("table X { Y:1; }", "illegal type");
   TestError("table X { Y:int; Y:int; }", "field already");
   TestError("struct X { Y:string; }", "only scalar");
@@ -1276,6 +1276,67 @@ void ParseUnionTest() {
                         "{ e_type: N_A, e: {} }"), true);
 }
 
+void UnionVectorTest() {
+  // load FlatBuffer fbs schema.
+  // TODO: load a JSON file with such a vector when JSON support is ready.
+  std::string schemafile;
+  TEST_EQ(flatbuffers::LoadFile(
+    "tests/union_vector/union_vector.fbs", false, &schemafile), true);
+
+  // parse schema.
+  flatbuffers::IDLOptions idl_opts;
+  idl_opts.lang_to_generate |= flatbuffers::IDLOptions::kCpp;
+  flatbuffers::Parser parser(idl_opts);
+  const char *include_directories[] = { "tests/union_vector", nullptr };
+  TEST_EQ(parser.Parse(schemafile.c_str(), include_directories), true);
+
+  flatbuffers::FlatBufferBuilder fbb;
+
+  // union types.
+  std::vector<uint8_t> types;
+  types.push_back(static_cast<uint8_t>(Character_Belle));
+  types.push_back(static_cast<uint8_t>(Character_Rapunzel));
+  types.push_back(static_cast<uint8_t>(Character_MuLan));
+
+  // union values.
+  std::vector<flatbuffers::Offset<void>> characters;
+  characters.push_back(CreateBelle(fbb, /*books_read=*/7).Union());
+  characters.push_back(CreateRapunzel(fbb, /*hair_length=*/6).Union());
+  characters.push_back(CreateMuLan(fbb, /*sward_attack_damage=*/5).Union());
+
+  // create Movie.
+  const auto movie_offset =
+      CreateMovie(fbb, fbb.CreateVector(types), fbb.CreateVector(characters));
+  FinishMovieBuffer(fbb, movie_offset);
+  uint8_t *buf = fbb.GetBufferPointer();
+
+  flatbuffers::Verifier verifier(buf, fbb.GetSize());
+  TEST_EQ(VerifyMovieBuffer(verifier), true);
+
+  const Movie *movie = GetMovie(buf);
+  TEST_EQ(movie->characters_type()->size(), 3);
+  TEST_EQ(
+      movie->characters_type()->GetEnum<Character>(0) == Character_Belle,
+      true);
+  TEST_EQ(
+      movie->characters_type()->GetEnum<Character>(1) == Character_Rapunzel,
+      true);
+  TEST_EQ(
+      movie->characters_type()->GetEnum<Character>(2) == Character_MuLan,
+      true);
+
+  TEST_EQ(movie->characters()->size(), 3);
+  const Belle *belle =
+      reinterpret_cast<const Belle*>(movie->characters()->Get(0));
+  TEST_EQ(belle->books_read(), 7);
+  const Rapunzel *rapunzel =
+      reinterpret_cast<const Rapunzel*>(movie->characters()->Get(1));
+  TEST_EQ(rapunzel->hair_length(), 6);
+  const MuLan *mu_lan =
+      reinterpret_cast<const MuLan*>(movie->characters()->Get(2));
+  TEST_EQ(mu_lan->sword_attack_damage(), 5);
+}
+
 void ConformTest() {
   flatbuffers::Parser parser;
   TEST_EQ(parser.Parse("table T { A:int; } enum E:byte { A }"), true);
@@ -1330,6 +1391,7 @@ int main(int /*argc*/, const char * /*argv*/[]) {
   InvalidUTF8Test();
   UnknownFieldsTest();
   ParseUnionTest();
+  UnionVectorTest();
   ConformTest();
 
   if (!testing_fails) {
diff --git a/tests/union_vector/union_vector.fbs b/tests/union_vector/union_vector.fbs
new file mode 100644
index 0000000000000000000000000000000000000000..4957cd862daff035d1fc90d74d21cb3dfcf39a5d
--- /dev/null
+++ b/tests/union_vector/union_vector.fbs
@@ -0,0 +1,24 @@
+table MuLan {
+  sword_attack_damage: int;
+}
+
+table Rapunzel {
+  hair_length: int;
+}
+
+table Belle {
+  books_read: int;
+}
+
+union Character {
+  MuLan,
+  Rapunzel,
+  Belle,
+}
+
+table Movie {
+  characters: [Character];
+}
+
+root_type Movie;
+file_identifier "MOVI";
diff --git a/tests/union_vector/union_vector_generated.h b/tests/union_vector/union_vector_generated.h
new file mode 100644
index 0000000000000000000000000000000000000000..180b3d99a86ba2b488324baccbc706e29f4ade45
--- /dev/null
+++ b/tests/union_vector/union_vector_generated.h
@@ -0,0 +1,300 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+
+#ifndef FLATBUFFERS_GENERATED_UNIONVECTOR_H_
+#define FLATBUFFERS_GENERATED_UNIONVECTOR_H_
+
+#include "flatbuffers/flatbuffers.h"
+
+struct MuLan;
+
+struct Rapunzel;
+
+struct Belle;
+
+struct Movie;
+
+enum Character {
+  Character_NONE = 0,
+  Character_MuLan = 1,
+  Character_Rapunzel = 2,
+  Character_Belle = 3,
+  Character_MIN = Character_NONE,
+  Character_MAX = Character_Belle
+};
+
+inline const char **EnumNamesCharacter() {
+  static const char *names[] = {
+    "NONE",
+    "MuLan",
+    "Rapunzel",
+    "Belle",
+    nullptr
+  };
+  return names;
+}
+
+inline const char *EnumNameCharacter(Character e) {
+  const size_t index = static_cast<int>(e);
+  return EnumNamesCharacter()[index];
+}
+
+template<typename T> struct CharacterTraits {
+  static const Character enum_value = Character_NONE;
+};
+
+template<> struct CharacterTraits<MuLan> {
+  static const Character enum_value = Character_MuLan;
+};
+
+template<> struct CharacterTraits<Rapunzel> {
+  static const Character enum_value = Character_Rapunzel;
+};
+
+template<> struct CharacterTraits<Belle> {
+  static const Character enum_value = Character_Belle;
+};
+
+bool VerifyCharacter(flatbuffers::Verifier &verifier, const void *obj, Character type);
+bool VerifyCharacterVector(flatbuffers::Verifier &verifier, const flatbuffers::Vector<flatbuffers::Offset<void>> *values, const flatbuffers::Vector<uint8_t> *types);
+
+struct MuLan FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+  enum {
+    VT_SWORD_ATTACK_DAMAGE = 4
+  };
+  int32_t sword_attack_damage() const {
+    return GetField<int32_t>(VT_SWORD_ATTACK_DAMAGE, 0);
+  }
+  bool Verify(flatbuffers::Verifier &verifier) const {
+    return VerifyTableStart(verifier) &&
+           VerifyField<int32_t>(verifier, VT_SWORD_ATTACK_DAMAGE) &&
+           verifier.EndTable();
+  }
+};
+
+struct MuLanBuilder {
+  flatbuffers::FlatBufferBuilder &fbb_;
+  flatbuffers::uoffset_t start_;
+  void add_sword_attack_damage(int32_t sword_attack_damage) {
+    fbb_.AddElement<int32_t>(MuLan::VT_SWORD_ATTACK_DAMAGE, sword_attack_damage, 0);
+  }
+  MuLanBuilder(flatbuffers::FlatBufferBuilder &_fbb)
+        : fbb_(_fbb) {
+    start_ = fbb_.StartTable();
+  }
+  MuLanBuilder &operator=(const MuLanBuilder &);
+  flatbuffers::Offset<MuLan> Finish() {
+    const auto end = fbb_.EndTable(start_, 1);
+    auto o = flatbuffers::Offset<MuLan>(end);
+    return o;
+  }
+};
+
+inline flatbuffers::Offset<MuLan> CreateMuLan(
+    flatbuffers::FlatBufferBuilder &_fbb,
+    int32_t sword_attack_damage = 0) {
+  MuLanBuilder builder_(_fbb);
+  builder_.add_sword_attack_damage(sword_attack_damage);
+  return builder_.Finish();
+}
+
+struct Rapunzel FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+  enum {
+    VT_HAIR_LENGTH = 4
+  };
+  int32_t hair_length() const {
+    return GetField<int32_t>(VT_HAIR_LENGTH, 0);
+  }
+  bool Verify(flatbuffers::Verifier &verifier) const {
+    return VerifyTableStart(verifier) &&
+           VerifyField<int32_t>(verifier, VT_HAIR_LENGTH) &&
+           verifier.EndTable();
+  }
+};
+
+struct RapunzelBuilder {
+  flatbuffers::FlatBufferBuilder &fbb_;
+  flatbuffers::uoffset_t start_;
+  void add_hair_length(int32_t hair_length) {
+    fbb_.AddElement<int32_t>(Rapunzel::VT_HAIR_LENGTH, hair_length, 0);
+  }
+  RapunzelBuilder(flatbuffers::FlatBufferBuilder &_fbb)
+        : fbb_(_fbb) {
+    start_ = fbb_.StartTable();
+  }
+  RapunzelBuilder &operator=(const RapunzelBuilder &);
+  flatbuffers::Offset<Rapunzel> Finish() {
+    const auto end = fbb_.EndTable(start_, 1);
+    auto o = flatbuffers::Offset<Rapunzel>(end);
+    return o;
+  }
+};
+
+inline flatbuffers::Offset<Rapunzel> CreateRapunzel(
+    flatbuffers::FlatBufferBuilder &_fbb,
+    int32_t hair_length = 0) {
+  RapunzelBuilder builder_(_fbb);
+  builder_.add_hair_length(hair_length);
+  return builder_.Finish();
+}
+
+struct Belle FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+  enum {
+    VT_BOOKS_READ = 4
+  };
+  int32_t books_read() const {
+    return GetField<int32_t>(VT_BOOKS_READ, 0);
+  }
+  bool Verify(flatbuffers::Verifier &verifier) const {
+    return VerifyTableStart(verifier) &&
+           VerifyField<int32_t>(verifier, VT_BOOKS_READ) &&
+           verifier.EndTable();
+  }
+};
+
+struct BelleBuilder {
+  flatbuffers::FlatBufferBuilder &fbb_;
+  flatbuffers::uoffset_t start_;
+  void add_books_read(int32_t books_read) {
+    fbb_.AddElement<int32_t>(Belle::VT_BOOKS_READ, books_read, 0);
+  }
+  BelleBuilder(flatbuffers::FlatBufferBuilder &_fbb)
+        : fbb_(_fbb) {
+    start_ = fbb_.StartTable();
+  }
+  BelleBuilder &operator=(const BelleBuilder &);
+  flatbuffers::Offset<Belle> Finish() {
+    const auto end = fbb_.EndTable(start_, 1);
+    auto o = flatbuffers::Offset<Belle>(end);
+    return o;
+  }
+};
+
+inline flatbuffers::Offset<Belle> CreateBelle(
+    flatbuffers::FlatBufferBuilder &_fbb,
+    int32_t books_read = 0) {
+  BelleBuilder builder_(_fbb);
+  builder_.add_books_read(books_read);
+  return builder_.Finish();
+}
+
+struct Movie FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+  enum {
+    VT_CHARACTERS_TYPE = 4,
+    VT_CHARACTERS = 6
+  };
+  const flatbuffers::Vector<uint8_t> *characters_type() const {
+    return GetPointer<const flatbuffers::Vector<uint8_t> *>(VT_CHARACTERS_TYPE);
+  }
+  const flatbuffers::Vector<flatbuffers::Offset<void>> *characters() const {
+    return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<void>> *>(VT_CHARACTERS);
+  }
+  bool Verify(flatbuffers::Verifier &verifier) const {
+    return VerifyTableStart(verifier) &&
+           VerifyField<flatbuffers::uoffset_t>(verifier, VT_CHARACTERS_TYPE) &&
+           verifier.Verify(characters_type()) &&
+           VerifyField<flatbuffers::uoffset_t>(verifier, VT_CHARACTERS) &&
+           verifier.Verify(characters()) &&
+           VerifyCharacterVector(verifier, characters(), characters_type()) &&
+           verifier.EndTable();
+  }
+};
+
+struct MovieBuilder {
+  flatbuffers::FlatBufferBuilder &fbb_;
+  flatbuffers::uoffset_t start_;
+  void add_characters_type(flatbuffers::Offset<flatbuffers::Vector<uint8_t>> characters_type) {
+    fbb_.AddOffset(Movie::VT_CHARACTERS_TYPE, characters_type);
+  }
+  void add_characters(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<void>>> characters) {
+    fbb_.AddOffset(Movie::VT_CHARACTERS, characters);
+  }
+  MovieBuilder(flatbuffers::FlatBufferBuilder &_fbb)
+        : fbb_(_fbb) {
+    start_ = fbb_.StartTable();
+  }
+  MovieBuilder &operator=(const MovieBuilder &);
+  flatbuffers::Offset<Movie> Finish() {
+    const auto end = fbb_.EndTable(start_, 2);
+    auto o = flatbuffers::Offset<Movie>(end);
+    return o;
+  }
+};
+
+inline flatbuffers::Offset<Movie> CreateMovie(
+    flatbuffers::FlatBufferBuilder &_fbb,
+    flatbuffers::Offset<flatbuffers::Vector<uint8_t>> characters_type = 0,
+    flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<void>>> characters = 0) {
+  MovieBuilder builder_(_fbb);
+  builder_.add_characters(characters);
+  builder_.add_characters_type(characters_type);
+  return builder_.Finish();
+}
+
+inline flatbuffers::Offset<Movie> CreateMovieDirect(
+    flatbuffers::FlatBufferBuilder &_fbb,
+    const std::vector<uint8_t> *characters_type = nullptr,
+    const std::vector<flatbuffers::Offset<void>> *characters = nullptr) {
+  return CreateMovie(
+      _fbb,
+      characters_type ? _fbb.CreateVector<uint8_t>(*characters_type) : 0,
+      characters ? _fbb.CreateVector<flatbuffers::Offset<void>>(*characters) : 0);
+}
+
+inline bool VerifyCharacter(flatbuffers::Verifier &verifier, const void *obj, Character type) {
+  switch (type) {
+    case Character_NONE: {
+      return true;
+    }
+    case Character_MuLan: {
+      auto ptr = reinterpret_cast<const MuLan *>(obj);
+      return verifier.VerifyTable(ptr);
+    }
+    case Character_Rapunzel: {
+      auto ptr = reinterpret_cast<const Rapunzel *>(obj);
+      return verifier.VerifyTable(ptr);
+    }
+    case Character_Belle: {
+      auto ptr = reinterpret_cast<const Belle *>(obj);
+      return verifier.VerifyTable(ptr);
+    }
+    default: return false;
+  }
+}
+
+inline bool VerifyCharacterVector(flatbuffers::Verifier &verifier, const flatbuffers::Vector<flatbuffers::Offset<void>> *values, const flatbuffers::Vector<uint8_t> *types) {
+  if (values->size() != types->size()) return false;
+  for (flatbuffers::uoffset_t i = 0; i < values->size(); ++i) {
+    if (!VerifyCharacter(
+        verifier,  values->Get(i), types->GetEnum<Character>(i))) { 
+      return false; 
+    }
+  }
+  return true;
+}
+
+inline const Movie *GetMovie(const void *buf) {
+  return flatbuffers::GetRoot<Movie>(buf);
+}
+
+inline const char *MovieIdentifier() {
+  return "MOVI";
+}
+
+inline bool MovieBufferHasIdentifier(const void *buf) {
+  return flatbuffers::BufferHasIdentifier(
+      buf, MovieIdentifier());
+}
+
+inline bool VerifyMovieBuffer(
+    flatbuffers::Verifier &verifier) {
+  return verifier.VerifyBuffer<Movie>(MovieIdentifier());
+}
+
+inline void FinishMovieBuffer(
+    flatbuffers::FlatBufferBuilder &fbb,
+    flatbuffers::Offset<Movie> root) {
+  fbb.Finish(root, MovieIdentifier());
+}
+
+#endif  // FLATBUFFERS_GENERATED_UNIONVECTOR_H_