迭代器和整数在模板参数中混淆 [英] Iterators and ints get confused in template parameter

查看:46
本文介绍了迭代器和整数在模板参数中混淆的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在写一个STL风格的数据容器,这个问题令人费解。

我。以下代码应说明问题:


// ---------------------------- ------------------------------

#include< iostream>

#include< list>


模板< typename T>

class MyClass

{

public:

void assign(size_t amount,const T& value)

{

std :: cout<<金额<< " " <<值<< std :: endl;

}


模板< typename InputIterator>

void assign(首先是InputIterator,最后是InputIterator)

{

while(first!= last)

{

std :: cout<< * first<< std :: endl;

++ first;

}

}

};


int main()

{

std :: list< intl1,l2;

l1.assign(10 ,5); // ok

l2.assign(l1.begin(),l1.end()); // ok


MyClass< intmc;

mc.assign(l1.begin(),l1.end()); // ok

mc.assign(10,5); //错误,错误的函数被调用

}

// ----------------------- -----------------------------------


我'' m使用gcc 4.1.2。


我明白*为什么*问题正在发生。但是,我不会理解为什么std :: list没有发生这种情况,而且我不知道如何解决这个问题(在...中)和std :: list一样)。


我查看了gcc C ++库中的std :: list源代码,

和我没有看到任何花哨的技巧被用于区分

两个assign()函数。然而它只适用于std :: list,但它并没有
使用我的代码。


任何指针?

I''m writing an STL-style data container, and this problem is puzzling
me. The following code should demonstrate the problem:

//----------------------------------------------------------
#include <iostream>
#include <list>

template<typename T>
class MyClass
{
public:
void assign(size_t amount, const T& value)
{
std::cout << amount << " " << value << std::endl;
}

template<typename InputIterator>
void assign(InputIterator first, InputIterator last)
{
while(first != last)
{
std::cout << *first << std::endl;
++first;
}
}
};

int main()
{
std::list<intl1, l2;
l1.assign(10, 5); // ok
l2.assign(l1.begin(), l1.end()); // ok

MyClass<intmc;
mc.assign(l1.begin(), l1.end()); // ok
mc.assign(10, 5); // error, wrong function gets called
}
//----------------------------------------------------------

I''m using gcc 4.1.2.

I understand *why* the problem is happening. However, I don''t
understand why it''s not happening with std::list, and I have no idea how
to get around the problem (in the same way as std::list does).

I have looked at the std::list source code in the gcc C++ libraries,
and I don''t see any fancy trick being used to differentiate between the
two assign() functions. Yet it just works with std::list, but it doesn''t
work with my code.

Any pointers?

推荐答案

Juha Nieminen写道:
Juha Nieminen wrote:

我正在写一个STL风格的数据容器,这个问题令人费解的是

我。以下代码应说明问题:


// ---------------------------- ------------------------------

#include< iostream>

#include< list>


模板< typename T>

class MyClass

{

public:

void assign(size_t amount,const T& value)

{

std :: cout<<金额<< " " <<值<< std :: endl;

}


模板< typename InputIterator>

void assign(首先是InputIterator,最后是InputIterator)

{

while(first!= last)

{

std :: cout<< * first<< std :: endl;

++ first;

}

}

};


int main()

{

std :: list< intl1,l2;

l1.assign(10 ,5); // ok

l2.assign(l1.begin(),l1.end()); // ok


MyClass< intmc;

mc.assign(l1.begin(),l1.end()); // ok

mc.assign(10,5); //错误,错误的函数被称为
I''m writing an STL-style data container, and this problem is puzzling
me. The following code should demonstrate the problem:

//----------------------------------------------------------
#include <iostream>
#include <list>

template<typename T>
class MyClass
{
public:
void assign(size_t amount, const T& value)
{
std::cout << amount << " " << value << std::endl;
}

template<typename InputIterator>
void assign(InputIterator first, InputIterator last)
{
while(first != last)
{
std::cout << *first << std::endl;
++first;
}
}
};

int main()
{
std::list<intl1, l2;
l1.assign(10, 5); // ok
l2.assign(l1.begin(), l1.end()); // ok

MyClass<intmc;
mc.assign(l1.begin(), l1.end()); // ok
mc.assign(10, 5); // error, wrong function gets called



10和5都有相同的类型,int。你有两个函数

''assign'',它们本质上是重载的。一个需要两个参数,

''size_t''和''int''(''T'',''int''代表''mc''对象),

其他需要两个参数,两个''InputIterator'',无论是哪个
可能是。哪个更好匹配?我猜你已经

" know"这一切都是因为你说你理解为什么问题

正在发生。然后,我将其拼写为其他人的好处。

Both ''10'' and ''5'' have the same type, ''int''. You have two functions
''assign'', which are essentially overloaded. One takes two arguments,
''size_t'' and ''int'' (the ''T'', which is ''int'' for ''mc'' object), the
other takes two arguments, both ''InputIterator'', whichever that
might be. Which is the better match? I am guessing that you already
"know" all this since you say that you "understand *why" the problem
is happening". I spelled it out for the benefits of the others, then.


}

// ---------- ------------------------------------------------ <无线电通信/>

我正在使用gcc 4.1.2。


我理解*为什么*问题正在发生。但是,我不会理解为什么std :: list没有发生这种情况,我不知道

如何解决这个问题(在和std :: list一样)。


我查看了gcc C ++库中的std :: list源代码,

和我没有看到任何花哨的技巧被用于区分

两个assign()函数。然而它只适用于std :: list,但是它没有使用我的代码。


任何指针?
}
//----------------------------------------------------------

I''m using gcc 4.1.2.

I understand *why* the problem is happening. However, I don''t
understand why it''s not happening with std::list, and I have no idea
how to get around the problem (in the same way as std::list does).

I have looked at the std::list source code in the gcc C++ libraries,
and I don''t see any fancy trick being used to differentiate between
the two assign() functions. Yet it just works with std::list, but it
doesn''t work with my code.

Any pointers?



您可以通过给出第二个模板参数来限制''assign''成员

模板接受的类型范围,例如,如果参数的类型不是
迭代器(SFINAE),那么
将成为一个ivalid类型。这是星期天,我的大脑运作不好,

因此我不能真正建议对代码进行任何更改...抱歉。


V

-

请在通过电子邮件回复时删除资金''A'

我没有回复热门回复,请不要问

You could limit the range of types accepted by the ''assign'' member
template by giving it a second template argument, for example, which
would become an ivalid type if the type of the argument is not
an iterator (SFINAE). It''s Sunday and my brain isn''t working well,
so I can''t really suggest any changes to the code... Sorry.

V
--
Please remove capital ''A''s when replying by e-mail
I do not respond to top-posted replies, please don''t ask


7月20日上午11点56分,Juha Nieminen< nos ... @ thanks.invalidwrote:
On Jul 20, 11:56 am, Juha Nieminen <nos...@thanks.invalidwrote:

我正在写一个STL风格的数据容器,这个问题令人费解。

我。以下代码应说明问题:


// ---------------------------- ------------------------------

#include< iostream>

#include< list>


模板< typename T>

class MyClass

{

public:

void assign(size_t amount,const T& value)

{

std :: cout<<金额<< " " <<值<< std :: endl;

}


模板< typename InputIterator>

void assign(首先是InputIterator,最后是InputIterator)

{

while(first!= last)

{

std :: cout<< * first<< std :: endl;

++ first;

}

}


};


int main()

{

std :: list< intl1,l2;

l1 .assign(10,5); // ok

l2.assign(l1.begin(),l1.end()); // ok


MyClass< intmc;

mc.assign(l1.begin(),l1.end()); // ok

mc.assign(10,5); //错误,错误的函数被调用}


// --------------------------- -------------------------------


我正在使用gcc 4.1 .2。


我明白*为什么*问题正在发生。但是,我不会理解为什么std :: list没有发生这种情况,而且我不知道如何解决这个问题(在...中)和std :: list一样)。


我查看了gcc C ++库中的std :: list源代码,

和我没有看到任何花哨的技巧被用于区分

两个assign()函数。然而它只适用于std :: list,但它并没有使用我的代码



任何指针?
I''m writing an STL-style data container, and this problem is puzzling
me. The following code should demonstrate the problem:

//----------------------------------------------------------
#include <iostream>
#include <list>

template<typename T>
class MyClass
{
public:
void assign(size_t amount, const T& value)
{
std::cout << amount << " " << value << std::endl;
}

template<typename InputIterator>
void assign(InputIterator first, InputIterator last)
{
while(first != last)
{
std::cout << *first << std::endl;
++first;
}
}

};

int main()
{
std::list<intl1, l2;
l1.assign(10, 5); // ok
l2.assign(l1.begin(), l1.end()); // ok

MyClass<intmc;
mc.assign(l1.begin(), l1.end()); // ok
mc.assign(10, 5); // error, wrong function gets called}

//----------------------------------------------------------

I''m using gcc 4.1.2.

I understand *why* the problem is happening. However, I don''t
understand why it''s not happening with std::list, and I have no idea how
to get around the problem (in the same way as std::list does).

I have looked at the std::list source code in the gcc C++ libraries,
and I don''t see any fancy trick being used to differentiate between the
two assign() functions. Yet it just works with std::list, but it doesn''t
work with my code.

Any pointers?



调用哪个函数?


你没有这个签名赋值的成员函数(int,

int);虽然int保证转换为size_t,但对于类T的对象没有这样的

保证。一个解决方案是将此成员函数添加到此类,另一个解决方案添加用户自定义

转换运算符。

PuzzleCracker

Which function gets called?

You don''t have a member function with this signature assign(int,
int ); While int is guaranteed to convert to size_t, there is no such
guarantees available for a object of class T. One solution is add
this member function to this class, another is add user-defined
conversion operator.

PuzzleCracker


Juha Nieminen写道:
Juha Nieminen wrote:

我查看了gcc C ++库中的std :: list源代码,

我没有看到任何花哨的技巧用于区分

两个assign()函数。
I have looked at the std::list source code in the gcc C++ libraries,
and I don''t see any fancy trick being used to differentiate between the
two assign() functions.



其实我错了。 assign()函数本身并没有使用任何

技巧,但是他们调用的内部函数似乎使用了某种模糊魔法来区分两者。案例。


有问题的代码填充了以_和__开头的名称,用于

示例:


typedef typename std :: __ is_integer< _InputIterator> :: __ type _Integral;


这似乎告诉我这不是标准库代码,

但是特定于gcc的代码(或者它正在使用的任何STL库)。因此它可能是非常便携的,试图复制这个实现

逐字。


任何建议如何我可以用标准STL代码解决这个问题

,最好不需要重新实现庞大的库?

(我也不想为assign()做专门化对于每个

可能的整数类型。)

Actually I was wrong. The assign() functions themselves don''t use any
trick, but the internal functions they call seem to use some kind of
obscure template magic to differentiate between the two cases.

The code in question is filled with names starting with _ and __, for
example:

typedef typename std::__is_integer<_InputIterator>::__type _Integral;

This seems to be telling me that this is not standard library code,
but code specific to gcc (or whatever STL library it''s using). Thus it
wouldn''t probably be very portable to try to copy this implementation
verbatim.

Any suggestions how I could solve this problem with standard STL code
only, and preferably without having to reimplement enormous libraries?
(Also I wouldn''t want to make specializations for assign() for each
possible integral type.)


这篇关于迭代器和整数在模板参数中混淆的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆