d:\program files\microsoft visual studio 8\vc\include\functional(282) : error C2535: 'bool std::binder1st<_Fn2>::operator ()(const wchar_t *const &) const' : member function already defined or declared
with
[
_Fn2=std::equal_to<const wchar_t*>
]
d:\program files\microsoft visual studio 8\vc\include\functional(276) : see declaration of 'std::binder1st<_Fn2>::operator ()'
with
[
_Fn2=std::equal_to<const wchar_t*>
]
d:\myprojects\test2005\test2005\test2005.cpp(890) : see reference to class template instantiation 'std::binder1st<_Fn2>' being compiled
with
[
_Fn2=std::equal_to<const wchar_t*>
]
где
template<class _Fn2>
class binder1st
: public unary_function<typename _Fn2::second_argument_type,
typename _Fn2::result_type>
{ // functor adapter _Func(stored, right)public:
typedef unary_function<typename _Fn2::second_argument_type,
typename _Fn2::result_type> _Base;
typedef typename _Base::argument_type argument_type;
typedef typename _Base::result_type result_type;
binder1st(const _Fn2& _Func,
const typename _Fn2::first_argument_type& _Left)
: op(_Func), value(_Left)
{ // construct from functor and left operand
}
result_type operator()(const argument_type& _Right) const// line 276
{ // apply functor to operandsreturn (op(value, _Right));
}
result_type operator()(argument_type& _Right) const
{ // apply functor to operands // line 282return (op(value, _Right));
}
protected:
_Fn2 op; // the functor to applytypename _Fn2::first_argument_type value; // the left operand
};
17.4.3.1 Reserved names
It is undefined for a C + + program to add declarations or definitions to namespace std or namespaces
within namespace std unless otherwise specified. A program may add template specializations for any
standard library template to namespace std. Such a specialization (complete or partial) of a standard
library template results in undefined behavior unless the declaration depends on a user-defined name of
external linkage and unless the specialization meets the standard library requirements for the original template.
Мне кажется, что тут самое место вспомнить фразу "Лучше бы тут иметь свой предикат"
Здравствуйте, igna, Вы писали:
I>Здравствуйте, Bell, Вы писали:
B>>Мне кажется, что тут самое место вспомнить фразу "Лучше бы тут иметь свой предикат"
I>С советом согласен, но спрашивающему не помогло бы. Въехал бы в точности туда же.
Согласен отчасти:
Комо, к примеру, такой пример скомпилит:
Здравствуйте, igna, Вы писали:
I>А пользу какую-нибудь от использования в этом случае const wchar_t*const вместо const wchar_t* придумать можно?
Кроме банального "запретить изменение значения указателя" ничего в голову не приходит.
А может быть кому-то нравится обилие const-ов в коде, или просто придает уверенности
Любите книгу — источник знаний (с) М.Горький
Re[2]: специализация std::equal_to<>
От:
Аноним
Дата:
30.08.07 15:23
Оценка:
Здравствуйте, igna, Вы писали:
I>Зачем тебе здесь второй const?
чтобы работало и для такого типа тоже (например, const LPCSTR)
Здравствуйте, Аноним, Вы писали:
А>чтобы работало и для такого типа тоже (например, const LPCSTR)
И без второго const будет работать.
Re[2]: специализация std::equal_to<>
От:
Аноним
Дата:
30.08.07 15:40
Оценка:
Здравствуйте, Bell, Вы писали:
B>Здравствуйте, Аноним, Вы писали:
B>Я бы начал отсюда: B>
B>17.4.3.1 Reserved names
B>It is undefined for a C + + program to add declarations or definitions to namespace std or namespaces
B>within namespace std unless otherwise specified. A program may add template specializations for any
B>standard library template to namespace std. Such a specialization (complete or partial) of a standard
B>library template results in undefined behavior unless the declaration depends on a user-defined name of
B>external linkage and unless the specialization meets the standard library requirements for the original template.
B>Мне кажется, что тут самое место вспомнить фразу "Лучше бы тут иметь свой предикат"
А как понимать "the declaration depends on a user-defined name of external linkage"?
Можно маленький примерчик?
Re[4]: специализация std::equal_to<>
От:
Аноним
Дата:
30.08.07 15:48
Оценка:
Здравствуйте, igna, Вы писали:
I>Здравствуйте, Аноним, Вы писали:
А>>чтобы работало и для такого типа тоже (например, const LPCSTR)
I>И без второго const будет работать.
Как он может тоже работать, если это другой тип?
Будет, конечно, работать, но не правильно
Потому что выберется дефолтная версия std::equal_to<>, а моя перегруженная — нет
I>Для const LPCSTR выберется та же твоя перегруженная что и для LPCSTR.
Ты же не объявляешь в дополнение к void f(int) еще и void f(const int). Собственно тут тебе и компилятор не позволит, как впрочем не позволил и в твоем случае.
Здравствуйте, Аноним, Вы писали:
А>А как понимать "the declaration depends on a user-defined name of external linkage"?
Можно добавлять только специализации, зависящие от определенных пользователем типов.
А>Можно маленький примерчик?
struct test{};//определенный пользователем типnamespace std
{
template<>
struct equal_to<test>{/**/};//Можно, ибо test - определенный пользователем тип.template<>
struct equal_to<const wchar_t*>{/**/};//Нельзя, ибо wchar_t - встроенный тип.
}
Любите книгу — источник знаний (с) М.Горький
Re[4]: специализация std::equal_to<>
От:
Аноним
Дата:
31.08.07 06:47
Оценка:
Здравствуйте, Bell, Вы писали:
B>Здравствуйте, Аноним, Вы писали:
А>>А как понимать "the declaration depends on a user-defined name of external linkage"? B>Можно добавлять только специализации, зависящие от определенных пользователем типов.
А>>Можно маленький примерчик?
B>
B>struct test{};//определенный пользователем тип
B>namespace std
B>{
B>template<>
B>struct equal_to<test>{/**/};//Можно, ибо test - определенный пользователем тип.
B>template<>
B>struct equal_to<const wchar_t*>{/**/};//Нельзя, ибо wchar_t - встроенный тип.
B>}
B>
Но LPCSTR тоже пользовательский тип, но он не имеет external linkage, так?
А как определить какой linkage имеет, к примеру struct test из Вашего примера?
Здравствуйте, Аноним, Вы писали:
А>Но LPCSTR тоже пользовательский тип, но он не имеет external linkage, так?
Нет, это алиас встроенного типа, полученный с помощью typedef — посмотри например в MSDN.
А>А как определить какой linkage имеет, к примеру struct test из Вашего примера?
Применительно к типам: Все типы за исключением локальных классов имеют external linkage.
3.5/2
A name is said to have linkage when it might denote the same object, reference, function, type, template,
namespace or value as a name introduced by a declaration in another scope:
— When a name has external linkage, the entity it denotes can be referred to by names from scopes of
other translation units or from other scopes of the same translation unit.
— When a name has internal linkage, the entity it denotes can be referred to by names from other scopes in
the same translation unit.
— When a name has no linkage, the entity it denotes cannot be referred to by names from other scopes.
Любите книгу — источник знаний (с) М.Горький
Re[7]: специализация std::equal_to<>
От:
Аноним
Дата:
31.08.07 07:38
Оценка:
Здравствуйте, igna, Вы писали:
I>>Для const LPCSTR выберется та же твоя перегруженная что и для LPCSTR.
I>Ты же не объявляешь в дополнение к void f(int) еще и void f(const int). Собственно тут тебе и компилятор не позволит, как впрочем не позволил и в твоем случае.
Как тогда объяснить, что в этом примере выбирается не моя специализация, а дефолтная?
И вообще, почему компилятор пропускает такую перегрузку?
Может всё-таки выбор перегруженной функции и специализации шаблона происходит по разному?
Ну а лишний const тебе тут помог? Куда ты его вставил, чтоб поехало как хочется?
P.S. typedef не определяет нового типа.
Re[6]: специализация std::equal_to<>
От:
Аноним
Дата:
31.08.07 08:05
Оценка:
Здравствуйте, Bell, Вы писали:
B>Здравствуйте, Аноним, Вы писали:
А>>Но LPCSTR тоже пользовательский тип, но он не имеет external linkage, так? B>Нет, это алиас встроенного типа, полученный с помощью typedef — посмотри например в MSDN.
А>>А как определить какой linkage имеет, к примеру struct test из Вашего примера? B>Применительно к типам: Все типы за исключением локальных классов имеют external linkage.
B>
B>3.5/2
B>A name is said to have linkage when it might denote the same object, reference, function, type, template,
B>namespace or value as a name introduced by a declaration in another scope:
B>— When a name has external linkage, the entity it denotes can be referred to by names from scopes of
B>other translation units or from other scopes of the same translation unit.
B>— When a name has internal linkage, the entity it denotes can be referred to by names from other scopes in
B>the same translation unit.
B>— When a name has no linkage, the entity it denotes cannot be referred to by names from other scopes.
Большое спасибо. Немного разобрался
Re[9]: специализация std::equal_to<>
От:
Аноним
Дата:
31.08.07 08:19
Оценка:
Здравствуйте, igna, Вы писали:
А>>Как тогда объяснить, что в этом примере выбирается не моя специализация, а дефолтная?
I>
I>Ну а лишний const тебе тут помог? Куда ты его вставил, чтоб поехало как хочется?
Я не говорю о тут, я говорю в принципе.
Я Вам на примере показал, что можно специализировать Шаблон<Тип> и Шаблон<const Тип>. Компилятору это понятно, и он выберает соответствующую версию специализации как и ожидается. Почему Вы от этого постоянно отрекаетесь?
Мне как раз и нужно специализировать Шаблон<Тип> и Шаблон<const Тип>. Вопрос был в том, почему не срабатывало наследование (см. исходный пост)
Здравствуйте, Аноним, Вы писали:
А>Я Вам на примере показал, что можно специализировать Шаблон<Тип> и Шаблон<const Тип>. Компилятору это понятно, и он выберает соответствующую версию специализации как и ожидается. Почему Вы от этого постоянно отрекаетесь?
Нет, не отрекаюсь, я знаю, что это возможно.
А>Мне как раз и нужно специализировать Шаблон<Тип> и Шаблон<const Тип>. Вопрос был в том, почему не срабатывало наследование (см. исходный пост)
Вот именно в том конкретном случае проблему можно было решить отказом от специализации для const Тип.
Re[11]: специализация std::equal_to<>
От:
Аноним
Дата:
31.08.07 08:35
Оценка:
Здравствуйте, igna, Вы писали:
А>>Мне как раз и нужно специализировать Шаблон<Тип> и Шаблон<const Тип>. Вопрос был в том, почему не срабатывало наследование (см. исходный пост)
I>Вот именно в том конкретном случае проблему можно было решить отказом от специализации для const Тип.
Спасибо за замечаение, но вопрос был немного о другом.
Здравствуйте, Аноним, Вы писали:
А>Как тогда объяснить, что в этом примере выбирается не моя специализация, а дефолтная?
Похоже, что запутались уже все
Попробуем немного упростить исходный пример — т.е. сначала сделаем специализацию для const int (аналог const wchar_t*const ):
Тип int, конечно же, отличен от const int. Поэтому специализация не подходит, и компилятор выбирает базовый шаблон. При этом тип переменной
sz не играет роли — выбор специализации происходит исключительно исходя из параметра шаблона equal_to<int> — т.е. int.
Теперь пример, приводящий к той же самой ошибке, что и в исходном посте:
int main()
{
const int sz = 0;
std::vector<int> v;
std::find_if(v.begin(), v.end(),
std::bind1st(std::equal_to<const int>(), sz));//Errorreturn 0;
}
Смотрим определение шаблона binder1st:
template<class _Fn2>
class binder1st
: public unary_function<typename _Fn2::second_argument_type,
typename _Fn2::result_type>
{ // functor adapter _Func(stored, right)public:
typedef unary_function<typename _Fn2::second_argument_type,
typename _Fn2::result_type> _Base;
typedef typename _Base::argument_type argument_type;
typedef typename _Base::result_type result_type;
binder1st(const _Fn2& _Func,
const typename _Fn2::first_argument_type& _Left)
: op(_Func), value(_Left)
{ // construct from functor and left operand
}
result_type operator()(const argument_type& _Right) const
{ // apply functor to operandsreturn (op(value, _Right));
}
result_type operator()(argument_type& _Right) const
{ // apply functor to operandsreturn (op(value, _Right));
}
protected:
_Fn2 op; // the functor to applytypename _Fn2::first_argument_type value; // the left operand
};
Теперь о проблемах:
Специализация сущностей из std встроенными типами ведет к неопределенному поведению.
Использованный синтаксис специализации некорректен, хотя компиляторы VC и переваривают его. Правильно нужно так: