【问题标题】:'using type' in C++ causes several errorsC++ 中的“使用类型”会导致几个错误
【发布时间】:2014-12-14 15:39:36
【问题描述】:

在我的问题type as returntype in c++ 中,我得到了一个答案: 给了我这样的结构:

template <int N>
struct int_type {
    using type = std::conditional_t<N <= 8, std::uint8_t,
                 std::conditional_t<N <= 16, std::uint16_t,
                 std::conditional_t<N <= 32, std::uint32_t,
                 std::conditional_t<N <= 64, std::uint64_t,
                 std::uintmax_t>>>>;
};

这似乎正是我所需要的,但实践看起来有何不同,因为由于以下错误,我无法编译它:

...Error: expected nested-name-specifier before 'type'
 using type = std::conditional_t<N <= 8, std::uint8_t,
       ^
...Error: using-declaration for non-member at class scope
...Error: expected ';' before '=' token
 using type = std::conditional_t<N <= 8, std::uint8_t,
            ^
...Error: expected unqualified-id before '=' token

我试图用谷歌搜索它,但我发现的帖子似乎都没有解决这个特定问题。谁能解释一下这段代码有什么问题?我对 C++ 很陌生

【问题讨论】:

  • conditional_t 是 C++14 中引入的辅助类型。您是否使用-std=c++14 标志进行编译?
  • @PeterT 就是这样,std::conditional_tconditional::type en.cppreference.com/w/cpp/types/conditional 的 typedef
  • @vsoftco 我的错,我应该更仔细地阅读它
  • 显然,该错误表明您甚至没有启用 C++11,更不用说 std::conditional_t 所需的 C++14。它需要 using-declaration 语法,因此编译器在 using 之后需要 nested name specifier 的错误
  • 我添加了 CONFIG += c++14 但仍然出现相同的错误。

标签: c++ templates types c++14


【解决方案1】:

只要你的编译器支持 stdlib 的&lt;type_traits&gt;std::conditional trait 定义别名模板,你的代码就是完全合法的。

但是,错误消息清楚地表明您甚至没有启用,因此using 根本不会被解析为别名。为此,请将-std=c++11-std=c++14 选项添加到您的配置中。

如果你不能,那么在 中你可以轻松实现你自己的conditional trait:

template <bool B, typename T, typename F>
struct conditional
{
    typedef T type;
};

template <typename T, typename F>
struct conditional<false, T, F>
{
    typedef F type;
};

template <int N>
struct int_type {
    typedef typename conditional<N <= 8, uint8_t,
                 typename conditional<N <= 16, uint16_t,
                 typename conditional<N <= 32, uint32_t,
                 typename conditional<N <= 64, uint64_t,
                 uintmax_t>::type>::type>::type>::type type;
};

中你可以使用std::conditional 而不是std::conditional_t,唯一的区别是你需要自己访问一个嵌套的typedef type,这是一个依赖的名字typename 关键字需要在嵌套名称说明符前面):

#include <cstdint>
#include <type_traits>

template <int N>
struct int_type {
    using type = typename std::conditional<N <= 8, std::uint8_t,
                 typename std::conditional<N <= 16, std::uint16_t,
                 typename std::conditional<N <= 32, std::uint32_t,
                 typename std::conditional<N <= 64, std::uint64_t,
                 std::uintmax_t>::type>::type>::type>::type;
};

中,您需要包含&lt;cstdint&gt; 而不是&lt;stdint.h&gt;。前者保证名称在 std 命名空间中定义(后者可能只在 global 命名空间中定义它们。

【讨论】:

    【解决方案2】:

    为了完整起见,我将在此处添加答案。

    您需要#include &lt;cstdint&gt;#include &lt;type_traits&gt;,然后使用 C++14 支持进行编译。代码:

    #include <type_traits>
    #include <cstdint>
    #include <iostream>
    
    template <int N>
    struct int_type {
        using type = std::conditional_t<N <= 8, std::uint8_t,
                     std::conditional_t<N <= 16, std::uint16_t,
                     std::conditional_t<N <= 32, std::uint32_t,
                     std::conditional_t<N <= 64, std::uint64_t,
                     std::uintmax_t>>>>;
    };
    
    int main()
    {
        int_type<10>::type t; // std::uint16_t
        t = 12;
        std::cout << t << std::endl;
    }
    

    现场示例:http://coliru.stacked-crooked.com/a/9352f3349f48bff4

    【讨论】:

      【解决方案3】:

      嗯,当您执行 typedef 时,编译器会告诉您出了什么问题。这些是依赖类型名,因此您需要在其前面添加一个“类型名”。所以这应该工作:

      #include <iostream>
      #include <type_traits>
      using namespace std;
      
      template <int N>
      struct int_type {
          using mytype = typename std::conditional<N <= 8, std::uint8_t,
                           typename std::conditional<N <= 16, std::uint16_t,
                             typename std::conditional<N <= 32, std::uint32_t,
                               typename std::conditional<N <= 64, std::uint64_t,
                                 std::uintmax_t
                               >::type
                             >::type
                           >::type
                         >::type;
      };
      

      【讨论】:

      • std::conditional_t不是typedef,而是别名模板,它在定义中自己添加了typename
      • @PiotrS。我的意思是我写了typedef std::conditional&lt;...&gt; type;,它显示了一个不同的错误
      • 删除答案的第一部分然后,尽管如此,该错误并不表示编译器无法解析依赖名称,而是缺少对别名的支持
      • @vsoftco 我很确定它们是依赖类型,这就是conditional_t 别名使用using conditional_t = typename conditional&lt;B,T,F&gt;::type; 的原因。你是对的,这不是 OPs 编译失败的原因,它与他的问题并不真正相关,但那些是依赖类型。
      • @PeterT 好的,你是对的,它们是依赖的,删除了我的评论,我的意思是它们属于当前实例化并且不需要 typename 限定符,因为编译器不是混淆了类型和最终的变量声明。参见例如en.cppreference.com/w/cpp/language/dependent_name 靠近底部,这里给出了一些关于 typename 用法的例子。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-10-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-06
      相关资源
      最近更新 更多