【问题标题】:Unexpected type due to template instantiation由于模板实例化导致的意外类型
【发布时间】:2015-10-10 18:51:19
【问题描述】:

我有以下(简化的)代码:

   template<typename T>
    class VarArray
    {
       typedef T* iterator;
    };

    void get_setpoints()
    {
         VarArray<int>::iterator mirror_id;
         int id;
         *mirror_id = id;
    }

*mirror_id 的类型是int。到现在为止还挺好。

现在我要在中间添加2个完全不相关的typedef:

template<typename T>
class VarArray
{
   typedef T* iterator;
};

typedef int MySpecialType;
typedef VarArray<MySpecialType> bool_t;

void get_setpoints()
{
     VarArray<int>::iterator mirror_id;
     int id;
     *mirror_id = id;
}

由于这些额外的 typedef,*mirror_id 的类型突然变成了MySpecialType,而我真的希望它是int 的类型。至少 Microsoft Visual Studio C++ 编译器和 EDG C++ 编译器似乎是这种情况。

我认为这很可怕的原因是一些嵌套的未知包含文件可能会突然将变量的类型更改为其他类型。你不知道它,如果你知道,就很难弄清楚它来自哪里。

所以我的问题是,这种行为是否符合 C++ 标准?如果是这样,是故意的吗?

【问题讨论】:

  • 你的例子有点奇怪,MySpecialType 只是int 的别名 (typedef) - 这意味着两者是等价的(它们都表示键入int)。你到底在害怕什么?
  • 我认为它不会将您的类型更改为其他类型。您的int 将保留int。你如何检查你的类型?
  • @FilipRoséen-refp。可能这有点特殊。我想编写一个禁止从“MySpecialType”转换到“MySpecialType”的编码标准规则。现在我得到一个误报“*mirror_id = id;”因为 EDG 认为它将“int”转换为“MySpecialType”。
  • @Rotislav。如果我不小心输入了“*mirror_id = &id;”,Visual Studio 编译器会显示“错误 C2440:'=':无法从 'int *' 转换为 'MySpecialType'”。真的很奇怪。

标签: c++ templates instantiation type-inference


【解决方案1】:

没有类型更改:MySpecialTypeint 的类型别名(同义词)。没错:这两个是同一类型。

在您的示例中,mirror_idVarArray&lt;int&gt;::iterator,但也是 MySpecialType*int*。这些都是相同的类型。

让您感到困惑的是 MSVC++ 没有调用与您在程序中使用相同名称的变量类型(这是 MSVC++ 的一个错误,应该修复)。

据我所知(从评论中)您期望所谓的“强类型定义”,C++ 不直接支持 - 您可以将 int 放入结构中,然后转发所有必要的操作。

class MySpecialType
{
    int wrapped_int;
public:
    MySpecialType(int a) : wrapped_int(a) { }
    explicit operator int() const { return wrapped_int; }
    int get() const { return wrapped_int; }
};

【讨论】:

  • 这不是我的问题。我的问题是这种类型更改是否符合 C++ 标准。
  • @PaulJansen 您的问题有缺陷,因为没有类型更改。查看答案。
猜你喜欢
  • 2016-04-15
  • 1970-01-01
  • 1970-01-01
  • 2015-11-23
  • 2020-12-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多