【发布时间】:2017-04-13 16:56:31
【问题描述】:
我正在寻找程序中一个非常奇怪的错误的原因。我发现奇怪的是,由于某种原因没有调用基类构造函数。这是要重现的代码:
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。
【问题讨论】:
-
std::enable_if_t<false>应该是硬错误,而不是替换失败。 -
确实你是对的。如果没有它,我会检查它是否仍然发生。
-
@TartanLlama:仅当要实例化所述模板时:-)
-
@GuillaumeRacicot:确实如此。所有的 SFINAE 修复最终都进入了 VS,我想它已经修复了。
-
使用 /W4 编译会给出“警告 C4700:使用了未初始化的局部变量 'test'”,并查看反汇编代码,它将传递给 main 的
ecx值存储到test.test中。绝对是一个错误。
标签: c++ visual-c++ visual-studio-2015 c++14