diff --git a/changelog.md b/changelog.md
--- a/changelog.md
+++ b/changelog.md
@@ -1,3 +1,4 @@
+- 0.9.1.5: Support multi-token types in C++ template arguments, see issue #125 and PR #126.
 - 0.9.1.4: Support GHC 8.10, including better C++ flags handling, see PR #121.
 - 0.9.1.3: Work around spurious test failures, see PR #118.
 - 0.9.1.2: Update haddock for `Language.C.Inline.Interruptible.pure`.
diff --git a/inline-c.cabal b/inline-c.cabal
--- a/inline-c.cabal
+++ b/inline-c.cabal
@@ -1,5 +1,5 @@
 name:                inline-c
-version:             0.9.1.4
+version:             0.9.1.5
 synopsis:            Write Haskell source files including C code inline. No FFI required.
 description:         See <https://github.com/fpco/inline-c/blob/master/README.md>.
 license:             MIT
diff --git a/src/Language/C/Types.hs b/src/Language/C/Types.hs
--- a/src/Language/C/Types.hs
+++ b/src/Language/C/Types.hs
@@ -179,37 +179,43 @@
           P.TypeSpecifier x -> modify $ \(a, b, c, d) -> (a, x:b, c, d)
           P.TypeQualifier x -> modify $ \(a, b, c, d) -> (a, b, x:c, d)
           P.FunctionSpecifier x -> modify $ \(a, b, c, d) -> (a, b, c, x:d)
-  -- Split data type and specifiers
-  let (dataTypes, specs) =
-        partition (\x -> not (x `elem` [P.SIGNED, P.UNSIGNED, P.LONG, P.SHORT])) pTySpecs
-  let illegalSpecifiers s = failConversion $ IllegalSpecifiers s specs
-  -- Find out sign, if present
-  mbSign0 <- case filter (== P.SIGNED) specs of
-    []  -> return Nothing
-    [_] -> return $ Just Signed
-    _:_ -> illegalSpecifiers "conflicting/duplicate sign information"
-  mbSign <- case (mbSign0, filter (== P.UNSIGNED) specs) of
-    (Nothing, []) -> return Nothing
-    (Nothing, [_]) -> return $ Just Unsigned
-    (Just b, []) -> return $ Just b
-    _ -> illegalSpecifiers "conflicting/duplicate sign information"
-  let sign = fromMaybe Signed mbSign
-  -- Find out length
-  let longs = length $ filter (== P.LONG) specs
-  let shorts = length $ filter (== P.SHORT) specs
-  when (longs > 0 && shorts > 0) $ illegalSpecifiers "both long and short"
-  -- Find out data type
-  dataType <- case dataTypes of
-    [x] -> return x
-    [] | longs > 0 || shorts > 0 -> return P.INT
-    [] -> failConversion $ NoDataTypes declSpecs
-    _:_ -> failConversion $ MultipleDataTypes declSpecs
-  -- Check if things are compatible with one another
-  let checkNoSpecs =
-        unless (null specs) $ illegalSpecifiers "expecting no specifiers"
-  let checkNoLength =
-        when (longs > 0 || shorts > 0) $ illegalSpecifiers "unexpected long/short"
-  let type2type dat = case dat of
+  tySpec <- type2type pTySpecs
+  return (Specifiers pStorage pTyQuals pFunSpecs, tySpec)
+  where
+    type2type pTySpecs = do
+      -- Split data type and specifiers
+      let (dataTypes, specs) =
+            partition (\x -> not (x `elem` [P.SIGNED, P.UNSIGNED, P.LONG, P.SHORT])) pTySpecs
+      let illegalSpecifiers s = failConversion $ IllegalSpecifiers s specs
+      -- Find out sign, if present
+      mbSign0 <- case filter (== P.SIGNED) specs of
+        []  -> return Nothing
+        [_] -> return $ Just Signed
+        _:_ -> illegalSpecifiers "conflicting/duplicate sign information"
+      mbSign <- case (mbSign0, filter (== P.UNSIGNED) specs) of
+        (Nothing, []) -> return Nothing
+        (Nothing, [_]) -> return $ Just Unsigned
+        (Just b, []) -> return $ Just b
+        _ -> illegalSpecifiers "conflicting/duplicate sign information"
+      let sign = fromMaybe Signed mbSign
+      -- Find out length
+      let longs = length $ filter (== P.LONG) specs
+      let shorts = length $ filter (== P.SHORT) specs
+      when (longs > 0 && shorts > 0) $ illegalSpecifiers "both long and short"
+      -- Find out data type
+      dataType <- case dataTypes of
+        [x] -> return x
+        [] | mbSign0 == Just Signed -> return P.INT -- "The Case of 'signed' not including 'signed int'"
+        [] | mbSign == Just Unsigned -> return P.INT -- "The Case of 'unsigned' not including 'unsigned int'"
+        [] | longs > 0 || shorts > 0 -> return P.INT
+        [] -> failConversion $ NoDataTypes declSpecs
+        _:_ -> failConversion $ MultipleDataTypes declSpecs
+      -- Check if things are compatible with one another
+      let checkNoSpecs =
+            unless (null specs) $ illegalSpecifiers "expecting no specifiers"
+      let checkNoLength =
+            when (longs > 0 || shorts > 0) $ illegalSpecifiers "unexpected long/short"
+      case dataType of
         P.Template s args -> do
           checkNoSpecs
           args' <- forM args type2type
@@ -219,7 +225,7 @@
           return $ TemplateConst s
         P.TemplatePointer s -> do
           checkNoSpecs
-          s' <- type2type s
+          s' <- type2type [s]
           return $ TemplatePointer s'
         P.TypeName s -> do
           checkNoSpecs
@@ -260,8 +266,6 @@
               return Double
         _ -> do
           error $ "untangleDeclarationSpecifiers impossible: " ++ show dataType
-  tySpec <- type2type dataType
-  return (Specifiers pStorage pTyQuals pFunSpecs, tySpec)
 
 untangleDeclarator
   :: forall i. Type i -> P.Declarator i -> Either UntangleErr (i, Type i)
@@ -409,7 +413,7 @@
         TypeName s -> [P.TypeName s]
         Struct s -> [P.Struct s]
         Enum s -> [P.Enum s]
-        Template s types -> [P.Template s (concat (map pTySpecs types))]
+        Template s types -> [P.Template s (map pTySpecs types)]
         TemplateConst s -> [P.TemplateConst s]
         TemplatePointer type' -> [P.TemplatePointer (head (pTySpecs type'))]
   in map P.StorageClassSpecifier storages ++
diff --git a/src/Language/C/Types/Parse.hs b/src/Language/C/Types/Parse.hs
--- a/src/Language/C/Types/Parse.hs
+++ b/src/Language/C/Types/Parse.hs
@@ -298,7 +298,7 @@
   | Struct CIdentifier
   | Enum CIdentifier
   | TypeName CIdentifier
-  | Template CIdentifier [TypeSpecifier]
+  | Template CIdentifier [[TypeSpecifier]]
   | TemplateConst String
   | TemplatePointer TypeSpecifier
   deriving (Typeable, Eq, Show)
@@ -380,14 +380,14 @@
     cidentParserWithNamespace =
       try (concat <$> sequence [cidentParser, (string "::"), cidentParserWithNamespace]) <|>
       cidentParser
-    templateArgType = try ((TemplatePointer <$> (type_specifier)) <* (string "*")) <|> try type_specifier <|> (TemplateConst <$> (many $ oneOf ['0'..'9']))
+    templateArgType = try ((TemplatePointer <$> (type_specifier)) <* (string "*")) <|> try type_specifier <|> (TemplateConst <$> (some $ oneOf ['0'..'9']))
     templateArgParser' = do
-      t <- templateArgType
+      t <- some (token templateArgType)
       _ <- string ","
       tt <- templateArgParser
       return $ t:tt
     templateArgParser =
-      try (templateArgParser') <|> ((:) <$> templateArgType <*> return [])
+      try (templateArgParser') <|> ((:) <$> some (token templateArgType) <*> return [])
 
 template_parser :: CParser i m => m TypeSpecifier
 template_parser = try $ templateParser cIdentStyle <?> "template name"
@@ -563,7 +563,11 @@
    Struct x -> "struct" <+> pretty x
    Enum x -> "enum" <+> pretty x
    TypeName x -> pretty x
-   Template x args -> pretty x <+> "<" <+> mconcat (intersperse "," (map pretty args))  <+> ">"
+   Template x args ->
+     -- This code generates a c++ code of "template-identifier<template-argument1,template-argument2,..>" like "std::vector<int>".
+     -- concat_with_space is used to concat multiple terms like "unsigned int".
+     let concat_with_space = mconcat . (intersperse " ") . (map pretty)
+     in pretty x <+> "<" <+> mconcat (intersperse "," (map concat_with_space args))  <+> ">"
    TemplateConst x -> pretty x
    TemplatePointer x -> pretty x <+> "*"
 
diff --git a/test/Language/C/Inline/ContextSpec.hs b/test/Language/C/Inline/ContextSpec.hs
--- a/test/Language/C/Inline/ContextSpec.hs
+++ b/test/Language/C/Inline/ContextSpec.hs
@@ -41,6 +41,10 @@
     shouldBeType (cty "bool") [t| CBool |]
   Hspec.it "converts void" $ do
     shouldBeType (cty "void") [t| () |]
+  Hspec.it "converts signed" $ do
+    shouldBeType (cty "signed") [t| CInt |]
+  Hspec.it "converts unsigned" $ do
+    shouldBeType (cty "unsigned") [t| CUInt |]
   Hspec.it "converts standard library types (1)" $ do
     shouldBeType (cty "FILE") [t| CFile |]
   Hspec.it "converts standard library types (2)" $ do
