是否存在隐式模板运算符<<(const ostream&,T)?

发布于 2024-10-31 14:54:29 字数 1814 浏览 1 评论 0 原文

我写了一个类,旨在表示向量(在线性代数意义上)。我刚刚开始写它,所以它还没有完成,但我已经粘贴了它和一些测试代码这里

我'我不太确定发生了什么事。我打算写一个重载运算符<<为了立即进行测试,所以我继续将其放入我的主函数中(这样我就可以使用编译器错误来确保我正确编写了它)。

这个警告是什么意思?为什么它要查看 v 的地址?我尝试从 v 中删除括号,最终得到 this,一堆可怕的模板错误: '

In function 'typename boost::range_const_iterator<C>::type boost::range_detail::boost_range_begin(const C&) [with C = vect<float, 3u>]':
/usr/local/include/boost/range/begin.hpp:164:   instantiated from 'typename boost::range_const_iterator<C>::type boost::begin(const T&) [with T = vect<float, 3u>]'
prelude/more_stdlib_ostreaming.hpp:64:   instantiated from 'void more_stdlib_ostreaming_detail::print_range(std::basic_ostream<_CharT, _Traits>&, const Range&) [with C = char, Tr = std::char_traits<char>, Range = vect<float, 3u>]'
prelude/more_stdlib_ostreaming.hpp:76:   instantiated from 'typename more_stdlib_ostreaming_detail::snd<typename R::iterator, std::basic_ostream<_CharT, _Traits>&>::type operator<<(std::basic_ostream<_CharT, _Traits>&, const R&) [with C = char, Tr = std::char_traits<char>, R = vect3f]'
t.cpp:42:   instantiated from here
Line 45: error: 'const class vect<float, 3u>' has no member named 'begin'`

不过,我大概能明白这里发生了什么。看起来它以某种方式使用 boost 的范围并尝试迭代我的容器,但它失败了,因为我没有定义 begin() 和 end() 。如果我使用 v(some_float) 而不是不使用括号来实例化 v,也会发生同样的事情。

那么,有两个问题:

  1. 为什么 v() 的行为与 v 不同?我认为声明一个没有括号的对象总是调用默认构造函数,而显式调用默认构造函数没有什么区别?

  2. 键盘的编译器(gcc 4.1.2)在这里做什么?它是否有一个模板可以自动尝试生成适当的运算符<

另外,请随意告诉我我在这里所做的任何其他愚蠢/错误/糟糕的风格(除了为了好玩而滚动我自己的矩阵数学库,我知道这是不必要的。我将其作为练习)

I have a class I've written, meant to represent vectors (in the linear algebra sense). I just started writing it so it isn't finished, but i've pasted it and some test code here

I'm not really sure what's going on. I was going to write an overloaded operator<< for testing in a second, so I went ahead and put it in my main function (so I could use compiler errors to make sure I'd written it properly).

What does this warning mean? why it is looking at the address of v? I tried removing the parentheses from v, and I end up with this, a bunch of horrible template errors:
`

In function 'typename boost::range_const_iterator<C>::type boost::range_detail::boost_range_begin(const C&) [with C = vect<float, 3u>]':
/usr/local/include/boost/range/begin.hpp:164:   instantiated from 'typename boost::range_const_iterator<C>::type boost::begin(const T&) [with T = vect<float, 3u>]'
prelude/more_stdlib_ostreaming.hpp:64:   instantiated from 'void more_stdlib_ostreaming_detail::print_range(std::basic_ostream<_CharT, _Traits>&, const Range&) [with C = char, Tr = std::char_traits<char>, Range = vect<float, 3u>]'
prelude/more_stdlib_ostreaming.hpp:76:   instantiated from 'typename more_stdlib_ostreaming_detail::snd<typename R::iterator, std::basic_ostream<_CharT, _Traits>&>::type operator<<(std::basic_ostream<_CharT, _Traits>&, const R&) [with C = char, Tr = std::char_traits<char>, R = vect3f]'
t.cpp:42:   instantiated from here
Line 45: error: 'const class vect<float, 3u>' has no member named 'begin'`

I can sort of see whats going on here, tho. It looks like it is somehow using boost's range for and trying to iterate over my container, and it is failing because I haven't defined begin() and end(). The same thing happens if I instantiate v using v(some_float) rather than without the parens.

So, two questions:

  1. Why is v() behaving differently than v? I thought that declaring a object without parens always calls the default ctor anyway, and explicitly calling the default ctor made no difference?

  2. What is codepad's compiler (gcc 4.1.2) doing here? Does it have a template that automatically tries to generate an appropriate operator<

Also, feel free to tell me anything else I'm doing stupid/wrong/bad style here (besides rolling my own matrix math library for fun, which I know is unnecessary. I'm doing it as an exercise)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

我早已燃尽 2024-11-07 14:54:29

首先,vect3f v(); 声明一个函数(名为v),不带参数并返回vect3f。并且为此函数指针调用正在调用的operator<<(它隐式转换为bool,因为函数指针没有重载)。

vect3f v; 是创建默认构造对象的正确方法。

不,编译器不会尝试生成 ostream&运算符<<(ostream& /* ... */) 为您服务。然而,所有基本类型甚至某些其他类型(例如 std::string)都有许多重载。

您可以在此处检查所有基本重载。

First of all, vect3f v(); declares a function (named v), taking no parameters and returning vect3f. And the operator<< that is being called is called for this function pointer (which is implicitly converted to bool, because there's no overload for function pointers).

vect3f v; is the correct way of creating default-constructed object.

And no, compiler won't try to generate ostream& operator<<(ostream& /* ... */) for you. There are however many overloads for all fundamental types and even some other types (such as std::string).

You can check all basic overloads here.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文