基类构造函数未被调用?

3

我正在搜索程序中一个非常奇怪的错误的原因。我发现奇怪的是,由于某种原因,基类构造函数没有被调用。以下是复现代码:

struct Parent {
    Parent() : test{9} {}

    int test;
};

template<typename T>
struct Child : T {
    Child() = default;

    // Will obviously not call this one
    template<typename... Args, std::enable_if_t<sizeof...(Args) == 9999>* = nullptr>
    Child(Args&&... args);
};

int main() {
    Child<Parent> test;
    std::cout << "This is a test: " << test.test << std::endl;
}

在我的情况下,程序只是崩溃或打印随机值。
如果我将子类更改为以下内容,则会调用构造函数:
template<typename T>
struct Child : T {
    Child() = default;
};

同样的情况也适用于此,构造函数仍然会被调用:
template<typename T>
struct Child : T {
    Child() {}

    // Will obviously not call this one
    template<typename... Args, std::enable_if_t<sizeof...(Args) == 9999>* = nullptr>
    Child(Args&&... args);
};

然而,使用第一个定义时,父构造函数不会被调用。我甚至尝试将父构造函数标记为已删除,但它仍然可以编译并崩溃!

以下是带有已删除构造函数的代码:

struct Parent {
    Parent() = delete;

    int test;
};

template<typename T>
struct Child : T {
    Child() = default;

    // Will obviously not call this one
    template<typename... Args, std::enable_if_t<sizeof...(Args) == 9999>* = nullptr>
    Child(Args&&... args);
};

int main() {
    Child<Parent> test;
    std::cout << "This is a test: " << test.test << std::endl;
}

我正在使用Visual Studio 2015更新3版本。


3
std::enable_if_t<false> 应该是一个硬错误,而不是替换失败。 - TartanLlama
代码不会导致未定义的行为吗?与这个进行比较。 - W.F.
1
@TartanLlama:只有在实例化该模板时才会这样 :-) - AndyG
1
@GuillaumeRacicot:确实看起来是这样的。考虑到所有已经进入VS的SFINAE修复,我想它已经被解决了。 - AndyG
3
使用 /W4 编译时会出现警告 C4700:“使用未初始化的本地变量'test'”,查看反汇编代码后发现将传入 main 函数的 ecx 值存储到了 test.test 中。这明显是一个 bug。 - 1201ProgramAlarm
显示剩余5条评论
1个回答

3

我正在使用最新的2015版本...看来我得升级到2017了...谢谢你的帮助。 - Guillaume Racicot

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接