diff --git a/hoppy-generator.cabal b/hoppy-generator.cabal
--- a/hoppy-generator.cabal
+++ b/hoppy-generator.cabal
@@ -1,5 +1,5 @@
 name: hoppy-generator
-version: 0.6.0
+version: 0.7.0
 synopsis: C++ FFI generator - Code generator
 homepage: http://khumba.net/projects/hoppy
 license: AGPL-3
diff --git a/src/Foreign/Hoppy/Generator/Hook.hs b/src/Foreign/Hoppy/Generator/Hook.hs
--- a/src/Foreign/Hoppy/Generator/Hook.hs
+++ b/src/Foreign/Hoppy/Generator/Hook.hs
@@ -22,6 +22,7 @@
   -- * Enum evaluation
   EnumEvaluator,
   EnumEvaluatorArgs (..),
+  EnumEvaluatorEntry (..),
   EnumEvaluatorResult (..),
   evaluateEnumsWithCompiler,
   evaluateEnumsWithDefaultCompiler,
@@ -39,6 +40,7 @@
 import Control.Monad.Writer (execWriter, tell)
 import Data.ByteString.Lazy (ByteString, hPut)
 import Data.ByteString.Builder (stringUtf8, toLazyByteString)
+import Data.List (splitAt)
 import qualified Data.Map as M
 import Data.Maybe (isJust, listToMaybe, mapMaybe)
 import qualified Data.Set as S
@@ -50,6 +52,7 @@
 import Foreign.Hoppy.Generator.Spec.Base
 import Foreign.Hoppy.Generator.Types (intT, llongT, longT, uintT, ullongT, ulongT)
 import Foreign.Hoppy.Generator.Util (withTempFile)
+import Foreign.Hoppy.Generator.Version (CppVersion (Cpp2011), activeCppVersion)
 import Foreign.Storable (Storable, sizeOf)
 import System.Exit (ExitCode (ExitFailure, ExitSuccess), exitFailure)
 import System.IO (hClose, hPutStrLn, stderr)
@@ -88,8 +91,8 @@
     -- being evaluated.
   , enumEvaluatorArgsSizeofIdentifiers :: [Identifier]
     -- ^ The list of identifiers that we need to compute sizeof() for.
-  , enumEvaluatorArgsEntryIdentifiers :: [Identifier]
-    -- ^ The list of identifiers to calculate values for.
+  , enumEvaluatorArgsEntries :: [EnumEvaluatorEntry]
+    -- ^ The list of entries to calculate values for.
   , enumEvaluatorArgsKeepOutputsOnFailure :: Bool
     -- ^ Whether to leave temporary build inputs and outputs on disk in case the
     -- calculation fails.  If failure does occur and this is true, then the
@@ -97,13 +100,27 @@
     -- (this is taken care of by the @calculateEnumValues*@ functions here.)
   }
 
+-- | An entry in an enumeration.  This also tracks whether the entry came from a
+-- scoped enum, for assertion reasons.
+data EnumEvaluatorEntry = EnumEvaluatorEntry
+  { enumEvaluatorEntryScoped :: Scoped
+    -- ^ Whether the entry comes from a scoped enum.
+  , enumEvaluatorEntryIdentifier :: Identifier
+    -- ^ The identifier referring to the entry.
+  }
+  deriving (Eq)
+
+instance Ord EnumEvaluatorEntry where
+  compare (EnumEvaluatorEntry _ i1) (EnumEvaluatorEntry _ i2) =
+    compare (OrdIdentifier i1) (OrdIdentifier i2)
+
 -- | Raw outputs parsed from the output of an enum evaluator.
 data EnumEvaluatorResult = EnumEvaluatorResult
   { enumEvaluatorResultSizes :: ![Int]
     -- ^ The sizeof() for each identifier in 'enumEvaluatorArgsSizeofIdentifiers'.
     -- The lengths of these two lists must match.
   , enumEvaluatorResultValues :: ![Integer]
-    -- ^ The numeric value for each identifier in 'enumEvaluatorArgsEntryIdentifiers'.
+    -- ^ The numeric value for each identifier in 'enumEvaluatorArgsEntries'.
     -- The lengths of these two lists must match.
   } deriving (Show)
 
@@ -178,7 +195,11 @@
 makeCppSourceToEvaluateEnums args =
   toLazyByteString $ stringUtf8 $ unlines $
   [ "#include <iostream>"
-  , ""
+  ] ++
+  (if any isEntryScoped $ enumEvaluatorArgsEntries args
+    then [ "#include <type_traits>" ]  -- We've asserted that we have C++11 in this case.
+    else []) ++
+  [ ""
   ] ++ [concatMap includeToString $
         S.elems $ reqsIncludes $ enumEvaluatorArgsReqs args] ++
   [ ""
@@ -190,10 +211,15 @@
          in "  std::cout << sizeof(" ++ rendered ++ ") << ' ' << " ++
             doubleQuote rendered ++ " << '\\n';") ++
   [ "  std::cout << \"#values\\n\";"
-  ] ++ for (enumEvaluatorArgsEntryIdentifiers args)
-       (\identifier ->
+  ] ++ for (enumEvaluatorArgsEntries args)
+       (\(EnumEvaluatorEntry scoped identifier) ->
          let rendered = renderIdentifier identifier
-         in "  std::cout << (" ++ rendered ++ ") << ' ' << " ++
+             numericExpr = case scoped of
+               Unscoped -> rendered
+               Scoped ->
+                 "static_cast<std::underlying_type<decltype(" ++ rendered ++ ")>::type>(" ++
+                 rendered ++ ")"
+         in "  std::cout << (" ++ numericExpr ++ ") << ' ' << " ++
             doubleQuote rendered ++ " << '\\n';") ++
   [ ""
   , "  return 0;"
@@ -212,7 +238,7 @@
   expectLine "#sizes"
   readSizes $ enumEvaluatorArgsSizeofIdentifiers args
   expectLine "#values"
-  readValues $ enumEvaluatorArgsEntryIdentifiers args
+  readValues $ map (\(EnumEvaluatorEntry _ i) -> i) $ enumEvaluatorArgsEntries args
   expectEof
   modify' $ \EnumEvaluatorResult
              { enumEvaluatorResultSizes = sizes
@@ -296,11 +322,12 @@
       -- Maybe Identifier: The enum's identifier, if we need to evaluate it.
       -- Reqs: Requirements to reference the enum.
       -- EnumValueMap: Entries, so that we can evaluate the auto ones.
-      enumExports :: [(ExtName, Maybe Type, Maybe Identifier, Reqs, EnumValueMap)]
+      enumExports :: [(ExtName, Maybe Type, Scoped, Maybe Identifier, Reqs, EnumValueMap)]
       enumExports = flip mapMaybe (M.elems allExports) $ \export ->
         flip fmap (getExportEnumInfo export) $ \(info :: EnumInfo) ->
           (enumInfoExtName info,
            enumInfoNumericType info,
+           enumInfoScoped info,
            case (enumInfoNumericType info, validateEnumTypes) of
              (Just _, False) -> Nothing  -- Don't need to evaluate sizeof().
              _ -> Just $ enumInfoIdentifier info,  -- Need to evaluate sizeof().
@@ -311,21 +338,42 @@
       -- so.
       sumReqs :: Reqs
       sizeofIdentifiersToEvaluate :: [OrdIdentifier]
-      entryIdentifiersToEvaluate :: [OrdIdentifier]
-      (sumReqs, sizeofIdentifiersToEvaluate, entryIdentifiersToEvaluate) =
-        (\(a, b, c) -> (a, b, S.toList $ S.fromList $ map OrdIdentifier c)) $
-        execWriter $ forM_ enumExports $ \(_, _, maybeIdent, reqs, entries) -> do
+      entriesToEvaluate :: [EnumEvaluatorEntry]
+      (sumReqs, sizeofIdentifiersToEvaluate, entriesToEvaluate) =
+        -- Deduplicate entries by passing them through a set.
+        (\(a, b, c) -> (a, b, S.toList $ S.fromList c)) $
+        execWriter $ forM_ enumExports $ \(_, _, scoped, maybeIdent, reqs, entries) -> do
           tell (reqs,
                 maybe [] (\i -> [OrdIdentifier i]) maybeIdent,
                 [])
           forM_ (M.toList $ enumValueMapValues entries) $ \(_, value) -> case value of
             EnumValueManual _ -> return ()
-            EnumValueAuto identifier -> tell (mempty, [], [identifier])
+            EnumValueAuto identifier -> tell (mempty, [], [EnumEvaluatorEntry scoped identifier])
 
+  -- We currently only support evaluation of scoped enum entries in C++11
+  -- and later, because we use std::underlying_type to perform the
+  -- conversion of those entries to integral types, rather than doing
+  -- e.g. two compilations, first determining their size.
+  when (activeCppVersion < Cpp2011) $ do
+    let scopedEnumsWithAutoEntries :: [ExtName] = flip mapMaybe enumExports $
+          \(extName, _, _, _, _, entries) ->
+            if any isAuto $ M.elems $ enumValueMapValues entries
+            then Just extName
+            else Nothing
+        (namesToShow, namesToSkip) = splitAt 10 scopedEnumsWithAutoEntries
+    unless (null scopedEnumsWithAutoEntries) $ do
+      hPutStrLn stderr $
+        "internalEvaluateEnumsForInterface': Automatic evaluation of enum values is not " ++
+        "requires at least " ++ show Cpp2011 ++ ", but we are compiling for " ++
+        show activeCppVersion ++ ", aborting.  Enums requesting evaluation are " ++
+        show namesToShow ++
+        (if not $ null namesToSkip then " (and more)" else "") ++ "."
+      exitFailure
+
   -- Evaluate the identifiers we are curious about, using the hook provided by
   -- the interface.
   evaluatorResult :: EnumEvaluatorResult <-
-    case (sizeofIdentifiersToEvaluate, entryIdentifiersToEvaluate) of
+    case (sizeofIdentifiersToEvaluate, entriesToEvaluate) of
       ([], []) -> return emptyEnumEvaluatorResult
       _ -> do
         let hooks = interfaceHooks iface
@@ -334,8 +382,7 @@
                    , enumEvaluatorArgsReqs = sumReqs
                    , enumEvaluatorArgsSizeofIdentifiers =
                        map ordIdentifier sizeofIdentifiersToEvaluate
-                   , enumEvaluatorArgsEntryIdentifiers =
-                       map ordIdentifier entryIdentifiersToEvaluate
+                   , enumEvaluatorArgsEntries = entriesToEvaluate
                    , enumEvaluatorArgsKeepOutputsOnFailure = keepBuildFailures
                    }
         hookEvaluateEnums hooks args >>=
@@ -344,7 +391,11 @@
                 "internalEvaluateEnumsForInterface': Failed to build and run program.  Aborting."
               exitFailure)
 
-  let evaluatedIdentifierSizes :: M.Map OrdIdentifier Int
+  let entryIdentifiersToEvaluate :: [OrdIdentifier]
+      entryIdentifiersToEvaluate =
+        map (OrdIdentifier . enumEvaluatorEntryIdentifier) entriesToEvaluate
+
+      evaluatedIdentifierSizes :: M.Map OrdIdentifier Int
       evaluatedIdentifierSizes =
         M.fromList $ zip sizeofIdentifiersToEvaluate $ enumEvaluatorResultSizes evaluatorResult
 
@@ -382,7 +433,8 @@
   -- Build a map containing the evaluated type and numeric values for all of
   -- the enums in the interface.
   evaluatedDataMap :: M.Map ExtName EvaluatedEnumData <-
-    fmap M.fromList $ forM enumExports $ \(extName, maybeNumericType, maybeIdent, _, values) -> do
+    fmap M.fromList $ forM enumExports $
+    \(extName, maybeNumericType, _, maybeIdent, _, values) -> do
       -- Build a map containing all of the numeric values in the enum.
       numMap :: M.Map [String] Integer <-
         fmap M.fromList $ forM (M.toList $ enumValueMapValues values) $ \(label, value) -> do
@@ -483,3 +535,10 @@
   numBytes info == bytes &&
   numMinBound info <= low &&
   numMaxBound info >= high
+
+isAuto :: EnumValue -> Bool
+isAuto (EnumValueAuto _) = True
+isAuto (EnumValueManual _) = False
+
+isEntryScoped :: EnumEvaluatorEntry -> Bool
+isEntryScoped (EnumEvaluatorEntry scoped _) = isScoped scoped
diff --git a/src/Foreign/Hoppy/Generator/Spec/Base.hs b/src/Foreign/Hoppy/Generator/Spec/Base.hs
--- a/src/Foreign/Hoppy/Generator/Spec/Base.hs
+++ b/src/Foreign/Hoppy/Generator/Spec/Base.hs
@@ -111,6 +111,8 @@
   Type (..),
   normalizeType,
   stripConst,
+  Scoped (..),
+  isScoped,
   -- * Functions and parameters
   Constness (..), constNegate,
   Purity (..),
@@ -1190,6 +1192,20 @@
   Internal_TConst t' -> stripConst t'
   _ -> t
 
+-- | Indicates whether an entity is scoped or unscoped.
+--
+-- This is used to distinguish unscoped enums (@enum@) or scoped ones (@enum
+-- class@ or @enum struct@).
+data Scoped =
+    Unscoped  -- ^ Indicates an unscoped entity (e.g. an enum).
+  | Scoped  -- ^ Indicates a scoped entity (e.g. an enum).
+  deriving (Eq, Ord, Show)
+
+-- | Returns true if a 'Scoped' value is scoped, and false if it is unscoped.
+isScoped :: Scoped -> Bool
+isScoped Unscoped = False
+isScoped Scoped = True
+
 -- | Whether or not @const@ is applied to an entity.
 data Constness = Nonconst | Const
                deriving (Bounded, Enum, Eq, Show)
@@ -1616,6 +1632,8 @@
     -- 'interfaceValidateEnumTypes').
   , enumInfoReqs :: Reqs
     -- ^ Requirements for accessing the enum.
+  , enumInfoScoped :: Scoped
+    -- ^ Whether the enum is scoped or unscoped.
   , enumInfoValues :: EnumValueMap
     -- ^ The entries in the enum.
   }
diff --git a/src/Foreign/Hoppy/Generator/Spec/Enum.hs b/src/Foreign/Hoppy/Generator/Spec/Enum.hs
--- a/src/Foreign/Hoppy/Generator/Spec/Enum.hs
+++ b/src/Foreign/Hoppy/Generator/Spec/Enum.hs
@@ -93,6 +93,8 @@
     -- using a C++ compiler.  If this is present however, Hoppy will use it, and
     -- additionally validate it against what the C++ compiler thinks, if
     -- validation is enabled (see 'interfaceValidateEnumTypes').
+  , enumScoped :: Scoped
+    -- ^ Whether the enum is scoped or unscoped.
   , enumValues :: EnumValueMap
     -- ^ The numeric values and names of the enum entires.
   , enumReqs :: Reqs
@@ -154,6 +156,7 @@
     , enumInfoIdentifier = enumIdentifier e
     , enumInfoNumericType = enumNumericType e
     , enumInfoReqs = enumReqs e
+    , enumInfoScoped = enumScoped e
     , enumInfoValues = enumValues e
     }
 
@@ -198,6 +201,7 @@
      extName
      identifier
      Nothing
+     Unscoped  -- Assume this is an unscoped enum.
      (let entries' = for entries $ \(num, words') -> (words', EnumValueManual num)
           entryNames = map fst entries'
       in EnumValueMap
@@ -221,7 +225,7 @@
   -> Maybe ExtName
   -- ^ An optional external name; will be automatically derived from the
   -- identifier if absent.
-  -> Bool
+  -> Scoped
   -- ^ Is the enum scoped (@enum class@ or @enum struct@)?  That is, are its
   -- entries scoped underneath its name, rather than being at the same level as
   -- its name (as with just @enum@).
@@ -235,10 +239,10 @@
      extName
      identifier
      Nothing
-     (let namespaceForValues =
-            if scoped
-            then identifier
-            else makeIdentifier $ butLast $ identifierParts identifier
+     scoped
+     (let namespaceForValues = case scoped of
+            Scoped -> identifier
+            Unscoped -> makeIdentifier $ butLast $ identifierParts identifier
           entries' =
             map (fmap (\name -> namespaceForValues `mappend` ident name) .
                  toAutoEnumValue)
