为什么此构造函数没有给出不完整的类型错误?

时间:2018-08-20 13:25:07

标签: c++ types language-lawyer

我有两个文件test.h和main.cpp,如下所示:

test.h

#include <memory>

class TestImpl;

template <typename... T>
void createConnection(T&&... Args)
{
    // 1. Why is this working if the constructor is in cpp?
    std::unique_ptr<TestImpl> pimpl(new TestImpl(std::forward<T>(Args)...));
    std::cout << "Done..." << std::endl;

    // 2. Why is this not working if the constructor call has no issues?
    pimpl->sayHello();
}

main.cpp

#include <iostream>

#include "test.h"

class TestImpl
{
public:
    TestImpl(const std::string& first, const std::string& second)
        : _first(first)
        , _second(second)
    {
    }

    void sayHello()
    {
        std::cout << "Hello ... " << std::endl;
    }

private:
    std::string _first;
    std::string _second;
};

int main()
{
    std::cout << "Hello World!" << std::endl;
    createConnection("ABC", "DEF");
    return 0;
}

从评论中可以明显看出,我的主要问题是为什么构造函数调用没有给出错误“无效使用不完整类型'Class TestImpl'...”。作为参考,我使用的是GCC 5.2,没有特定标志。

1 个答案:

答案 0 :(得分:10)

简单地说,GCC不必拒绝您的程序,而Clang不必接受它。格式错误,无需诊断。由于for i in range(len(l)): the_tuple = l[i] if isinstance(the_tuple[0], str) and the_tuple[0].startswith('__label__'): l[i] = (the_tuple[0][len('__label__'):], the_tuple[1]) # you can also replace "len('__label__')" by "8" to increase performances # but I think Python already optimizes it 不完整,因此您的模板违反了

  

[temp.res]/8

     

...该程序格式不正确,无需进行诊断,如果:

     
      模板紧随其定义之后的假设实例化将由于结构不正确而形成错误   取决于模板参数,或者   在假设的实例中,这种构造的解释不同于对构造的解释。   模板的任何实际实例中对应的构造。   

有人可能会说被调用的构造函数是依赖的,但类名肯定不是!

在我们的例子中,假设在模板定义之后立即包含两个字符串的实例化实例化将产生与程序中实例化点不同的结果。这是因为类名本身(又是不依赖的)在两个上下文中具有不同的含义。

这不是有效的模板定义。但是,由于不需要进行诊断,因此海湾合作委员会(GCC)正在这里留有余地。


这在项目符号下的注释中进行了简要总结,虽然不是规范性的,但描述了您的情况:

  

在以下情况下可能会发生这种情况:

     
      
  • 在非依赖名称中使用的类型在定义模板时不完整,但在定义模板时不完整   实例化,或者
  •