Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 10.09.2011, 19:56   #1
Syuf
Форумчанин
 
Аватар для Syuf
 
Регистрация: 02.02.2010
Сообщений: 599
Вопрос Проблемы с шаблонами

Собственно, наткнулся на непонятную для меня вещь (возможно просто не хватает знаний в области шаблонов), связанную с этими кусками кода:
Так компилится:
Код:
struct C
{
	void f() {}
};


template <typename Class>
class ptr_t
{
public:
	ptr_t(void (Class::*)()) {}
};


template <typename Class>
ptr_t<Class> ptr(void (Class::*fun)())
{
	return ptr_t<Class>(fun);
}


int main()
{
	ptr<C>(&C::f);

	return 0;
}
А так не хочет:
Код:
struct C
{
	void f() {}
};


template <typename Class>
class ptr_t
{
public:
	ptr_t(void (Class::*)()) {}
};


template <typename Class>
void ptr(void (Class::*fun)())
{
	ptr_t<Class>(fun); // error C2082: redefinition of formal parameter 'fun'
	// error C2512: 'ptr_t<Class>' : no appropriate default constructor available
}


int main()
{
	ptr<C>(&C::f);

	return 0;
}
MSVS2008, Windows 7. В чем может быть проблема?
Возможно, это не связано с шаблонами, а только с указателем на функцию; возможно, я просто что-то упустил.
"Лишь то читается легко, что написано с трудом; что в час написано, то в час и позабыто."

Последний раз редактировалось Syuf; 10.09.2011 в 19:59.
Syuf вне форума Ответить с цитированием
Старый 10.09.2011, 22:56   #2
Bubaleh
Пользователь
 
Регистрация: 08.09.2011
Сообщений: 18
По умолчанию

Во втором случае ты не создаешь объекта никакого, вот и выскакивает ошибка!
Если исправить на :

Код:
ptr_t<Cl> a(fun);
то все компилится нормально!

Последний раз редактировалось Bubaleh; 10.09.2011 в 23:06.
Bubaleh вне форума Ответить с цитированием
Старый 10.09.2011, 23:03   #3
Bubaleh
Пользователь
 
Регистрация: 08.09.2011
Сообщений: 18
По умолчанию

А все,понял!!!
В первом случае,кажется,просто временный объект создается в качестве возвращаемого значения...а во втором случае ты просто переопределить значение пытаешься!!!
Если ты ту же строчку и в первом примере напишешь без return,то та же фигня будет!!!
Bubaleh вне форума Ответить с цитированием
Старый 11.09.2011, 02:50   #4
Carbon
JAVA BEAN
Участник клуба
 
Аватар для Carbon
 
Регистрация: 22.04.2007
Сообщений: 1,329
По умолчанию

Код:
class A
{
public:

	A(int) {}

};


void func(int a)
{
	A(a); // попытка определить переменную класса A через дефолтный конструктор
        // return A(a); - однозначно возврат объекта класса A через конструктор с 1 параметром, потому что в return нельзя объявлять переменную
}
Код:
ptr_t<Class> fake(fun);
Carbon вне форума Ответить с цитированием
Старый 11.09.2011, 02:55   #5
onewho
Форумчанин
 
Регистрация: 29.09.2010
Сообщений: 636
По умолчанию

ну вроде как эта срочка
Код:
return ptr_t<Class>(fun);
идентична
Код:
return (ptr_t<Class>)fun;
а эта строчка
Код:
ptr_t<Class>(fun);
идентична
Код:
ptr_t<Class> fun;
вот и ругается на редифинишен.
onewho вне форума Ответить с цитированием
Старый 11.09.2011, 19:33   #6
Syuf
Форумчанин
 
Аватар для Syuf
 
Регистрация: 02.02.2010
Сообщений: 599
По умолчанию

Спасибо всем за ответы. Я так понял, что в такой нотации можно создавать экземпляр класса, используя только литералы в качестве аргументов (по крайней мере с ними компилится). Или писать полное имя, т.е.:
Код:
struct C
{
	void f() {}
};


template <typename Class>
class ptr_t
{
public:
	ptr_t(void (Class::*)()) {}
};


template <typename Class>
void ptr(void (Class::*fun)())
{
	ptr_t<Class>::ptr_t(fun);
}


int main()
{
	ptr<C>(&C::f);

	return 0;
}
"Лишь то читается легко, что написано с трудом; что в час написано, то в час и позабыто."

Последний раз редактировалось Syuf; 11.09.2011 в 19:47.
Syuf вне форума Ответить с цитированием
Старый 11.09.2011, 21:43   #7
Carbon
JAVA BEAN
Участник клуба
 
Аватар для Carbon
 
Регистрация: 22.04.2007
Сообщений: 1,329
По умолчанию

Syuf, ну или так. А вообще, ударенный по голове сишный компилятор считает:
Код:
Class(a); // объявление переменной a
Class(a, b); // Вызов конструктора с параметрами a, b, а не объявление 2-х переменный, как можно подумать

Class a(); // объявление внутренней функции, хотя стандарт это запрещает
Class a(b); // объявление объекта a через вызов конструктора с параметром b, а не объявление внутренней функции с параметром дефолтного типа int т.е. (а ведь очень хотелось!!!), а что стандарт это тоже запрещает чо, как по логике можно подумать
Carbon вне форума Ответить с цитированием
Старый 11.09.2011, 22:12   #8
Syuf
Форумчанин
 
Аватар для Syuf
 
Регистрация: 02.02.2010
Сообщений: 599
По умолчанию

Спасибо, Carbon, не знал, что можно объявлять переменные так:
Код:
Class(a);
Кстати, а дефолтный int вроде бы не поддерживается плюсами?
Цитата:
с параметром дефолтного типа int
"Лишь то читается легко, что написано с трудом; что в час написано, то в час и позабыто."
Syuf вне форума Ответить с цитированием
Старый 11.09.2011, 22:32   #9
Carbon
JAVA BEAN
Участник клуба
 
Аватар для Carbon
 
Регистрация: 22.04.2007
Сообщений: 1,329
По умолчанию

Syuf, не-а. Я не уверен, но он в современном си либо тоже не поддерживается, либо компилер на него дико орёт.
Carbon вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
проблемы с IE Tradua HTML и CSS 1 05.08.2011 06:54
Проблемы с БД Verwolf C/C++ Базы данных 2 22.05.2011 09:52
проблемы с if Vergil Общие вопросы C/C++ 8 21.04.2010 21:43
Помогите пожалуйста с ШАБЛОНАМИ<Template> Suren Общие вопросы C/C++ 2 16.06.2009 19:16
Работа с шаблонами Viteef PHP 3 30.07.2007 03:39