gpt4 book ai didi

c++ - 非常奇怪的行为 : Class with template constructor with only one argument

转载 作者:行者123 更新时间:2023-11-30 00:39:33 24 4
gpt4 key购买 nike

最近我遇到了一个奇怪的行为,当我有一个类的模板构造函数只接受一个参数时。该类在某些情况下根本无法初始化。

#include <iostream>

struct Foo
{
template<typename T>
Foo(const T& x)
{
std::cout << "--" << x << std::endl;
}
};

int main(int, char**)
{
Foo f(std::string());

std::cout << "++" << f << std::endl;
return 0;
}

我拥有的是一个 Foo 结构,其中包含您看到的构造函数。在 main 中,我创建了一个带有空 std::string 的新 Foo 实例。该示例编译并输出为:

++1

什么鬼???您可能已经注意到 this 存在三个问题。首先,从未调用过构造函数,其次,f 被打印为“1”,第三,没有重载的 operator<< 使用 cout 打印 Foo,尽管编译器从未提示过。这意味着 f 不是 Foo 的一种类型。

我稍微改变一下这个例子:

int main(int, char**)
{
Foo f(std::string(""));

std::cout << "++" << f << std::endl;
return 0;
}

...编译器会抛出一个错误,指出没有重载运算符<<,这是正常的。

int main(int, char**)
{
Foo f(std::string("Hello"));
return 0;
}

现在的输出是:

--Hello

这又是正常的。

问题是当向 Foo::Foo 传递一个空对象时,无论它是 std::string() 或 float() 还是 any_type()。我已经在 GCC 4.4 和 4.6 中测试了这个例子,我发现这种行为非常出乎意料。

你有什么看法?这是 GCC 错误还是我在这里遗漏了什么?

最佳答案

Foo f(std::string());

它不会创建 Foo 类型的实例,如您所想。

相反,这声明了一个名称为 f 的函数,其返回类型为 Foo , 参数类型是函数类型(不带参数并返回 std::string )。

它等同于:

Foo f(std::string (*)()); //same as yours

这和您的函数声明的唯一区别是,在您的情况下,参数类型是函数类型(最终会退化为函数指针类型 无论如何),在我的例子中,参数类型是 function pointer type(不需要衰减到 pointer 类型)。

至于为什么打印++1是因为它调用了 operator<<这需要 void*作为参数,此函数打印函数的地址。

现在如果你想声明一个对象,那么你需要使用额外的括号作为:

Foo f((std::string())); //notice the extra parens!

这声明了一个对象,并调用了构造函数:http://ideone.com/Px815


另请参阅本主题:

关于c++ - 非常奇怪的行为 : Class with template constructor with only one argument,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8573222/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com