Letysite.ru

IT Новости с интернет пространства
1 просмотров
Рейтинг статьи
1 звезда2 звезды3 звезды4 звезды5 звезд
Загрузка...

C pointer to member function

C++, эквивалентность между pointer-to-functions и pointer-to-member-functions?

Я привык думать о функциях-членах как о специальном случае обычных функций, где функции-члены имеют дополнительный параметр в начале списка параметров для указателя ‘this’, то есть объекта, на который должна действовать функция-член. Я использовал boost::function таким образом в прошлом и никогда не сталкивался с какими-либо проблемами:

Но я видел этот синтаксис для указателей на функции-члены:

В этом синтаксисе параметр ‘this’ не отображается. Что заставило меня задуматься, действительно ли под капотом pointer-to-member-functions-отдельный зверь, и что boost заботился о деталях для меня.

Что стандарт диктует о размещении параметра ‘this’? Возможно, только на моем компиляторе сначала появляется дополнительный аргумент ‘this’, и, возможно, на других компиляторах он может быть в конце? Мне просто повезло, что мой образ мышления согласуется с тем, как мои компиляторы (GCC4, VS2005) справляются с этим? Является ли pointer-to-member-functions всегда просто частным случаем pointer-to-functions с дополнительным параметром или компилятор может реализовать их по-другому?

9 Ответов

Стандарт почти ничего не говорит о том, где должен быть размещен указатель this , и на самом деле довольно часто используется другое соглашение о вызове для функций-членов. (Таким образом, указатель ‘this’ — это не просто дополнительный первый аргумент, он фактически хранится в другом месте, чем обычно находится первый arg)

В частности, MSVC использует соглашение о вызове thiscall для функций-членов, а stdcall -для других функций. http://www.hackcraft.net/cpp/MSCallingConventions/#thiscall описывает различия между ними, но обратите внимание, что thiscall хранит указатель this в регистре ECX , а stdcall хранит все параметры в стеке.

Вам определенно лучше относиться к ним как к совершенно разным типам. Указатель на функцию-член — это не просто указатель на функцию с дополнительным параметром.

Указатель this не хранится вдоль указателя на член (указатели на функции-члены являются частным случаем этого). Если вы просто сделаете это

тогда сохраняется только информация о том, какая функция-член должна быть вызвана для объекта, который вы позже должны предоставить. Если вы хотите вызвать его, вы должны передать объект, откуда компилятор получит указатель this .

Указатель на функцию-член — это просто указатель на член, чей тип (на который указывают) является типом функции. Стандарт говорит, что указатели на функции-члены не имеют своего собственного «member function type», на который они указывают, и который каким-то образом включал бы этот тип указателя.

fun в этом коде является типом функции. Тип, который имеет функция «normal». A pointer-to-function, в отличие от A member-function-pointer, является просто указателем на функцию, имеющую этот тип:

В то время как pointer-to-member-function имеет дополнительный уровень указателя члена на вершине этого типа функции.

Что-то о указателе this и о том, как он относится к объекту, на который он указывает (не технический, а просто теоретический материал):

Каждая функция-член имеет скрытый параметр, называемый implicit object parameter , который имеет тип MyObject& или MyObject const& в зависимости от того, есть ли у вас функция-член const или nonconst. Объект, вызываемый функцией-членом на o , является implied object argument , который передается параметру. В теории стандарта, который составляет правила, описывающие, как вызываются функции-члены, неявный параметр объекта является первым скрытым параметром. Это концептуально, и не означает, что это реальный случай в реализациях. Аргумент неявного объекта затем привязывается к этому параметру неявного объекта, что может привести к неявным преобразованиям (поэтому, если вы вызываете функцию-член const для неконстантного объекта, преобразование квалификации преобразуется из MyObject в MyObject const& . Это то, что делает неконстантные функции лучшим выбором, чем функции const для вызова, для неконстантного объекта). Например, можно сказать, что в этом коде:

Что подразумеваемый аргумент объекта a типа A связан с неявным параметром объекта типа A const& , на объект которого затем указывает указатель this , имеющий здесь тип A const* . Важно отметить, что неявный параметр объекта является только теоретической конструкцией, формализующей, как составляются правила для вызова функции-члена (и конструкторы не включают их), в то время как указатель this фактически существует. this -это указатель, потому что когда был введен this , C++ еще не имел ссылок.

Я надеюсь, что это поможет вам понять суть дела.

Отличная статья о указателях функций-членов — это указатели функций-членов CodeProject и максимально быстрые делегаты C++. В этой статье описываются указатели функций-членов из простых случаев вплоть до виртуальных указателей функций-членов с множественным наследованием. В качестве бонуса он обеспечивает реализацию делегатов, которые могут быть действительно полезны.

Да, pointers-to-functions и pointers-to-members-совершенно разные звери. Указатели на члены должны быть предоставлены экземпляру объекта для разыменования с помощью операторов ->* или .* . Параметр this не используется при создании pointer-to-member, поскольку this определяется при использовании указателя на элемент (объект слева от ->* или .* ).

Обратите внимание, что разница между функцией pointer-to-member и переменной pointer-to-member, вероятно, меньше, чем между функцией pointer-to-member и обычным указателем функции.

Как правило, функции-члены и обычные функции могут иметь совершенно разные соглашения о вызовах, поэтому вы не можете выполнять приведение между ними.

Обратите внимание, что размер pointer-to-member-function может быть разным при использовании разных компиляторов.

Еще одно замечание, как написано в старом блоге New Thing :

Размер a pointer-to-member-function может измениться в зависимости от класса.

Они определенно разные типы, и любые допущения, которые вы сделаете, будут специфичны для платформы/компилятора.

Эта страница содержит больше информации о реализации точек функций-членов, чем я когда-либо хотел бы знать, включая детали реализации для многочисленных популярных компиляторов.

Чтобы ответить на все вопросы: Да, это особые указатели, отличные от обычных указателей. Да, boost::function узнает их.

Стандарт ничего не говорит о внутренних деталях стеков вызовов. На самом деле, многие компиляторы могут использовать целочисленные rergisters, регистры с плавающей запятой и/или стек в зависимости от фактического списка аргументов. Указатель ‘this’ — это всего лишь еще один частный случай.

Boost::function решает эту проблему с помощью двух внутренних путей кода. Вы можете убедиться в этом, проверив стек вызовов для этих двух случаев. Если ваш boost::function хранит указатель на функцию-член, то operator() разделит список аргументов. Первый аргумент используется в качестве объекта, на котором вызывается функция-член с остальными аргументами.

Чтобы дополнить ответ всех остальных, Boost.Function работает, специализируя оператор присваивания на указателях функций-членов, чтобы позволить ему обнаружить, когда вы передали один из них. Когда вы вызываете эту функцию, она внутренне переинтерпретирует ее в соответствующий метод вызова указателя функции-члена ( (obj->*fun)(args) ).

Я думаю, что вы можете найти эту ссылку довольно интересной:

Это очень хорошее описание всего, что вы хотели бы знать о pointer-to-members.

Похожие вопросы:

У меня есть немного кода COM, который использует указатели интерфейса. Оригинальный автор кода реализовал функции, которые возвращают указатель интерфейса следующим образом: HRESULT Query ( IN BSTR.

Итак, вот ситуация: я использую C++, SDL и GLConsole в сочетании. У меня есть класс, SDLGame , который имеет Init() , Loop() , Render() и т. д.-По сути, он содержит логику для моего игрового класса.

Как я могу hash (std::tr1::hash или boost::hash) в c++ pointer-to-member-function? Пример: У меня есть несколько bool (Class:: * functionPointer) () (не статический), которые указывают на несколько.

У меня есть шаблон класса, который имеет статический pointer-to-member, как это: template class Queue < T* head; T* tail; static T* T::*pnext; >; Мой вопрос.

Рассмотрим классы с переменными-членами, например: struct A < int a; char b; >; struct B < double c; bool d; >; Можно ли объявить класс шаблона, который принимает в качестве своего шаблона аргумент.

Есть ли какой-нибудь способ назначить pointer-to-class-member так, чтобы он указывал на сам класс? Это фактически означало бы, что результатом применения указателя члена к экземпляру класса будет.

Я пробовал искать это, но каждый термин, о котором я думаю, заканчивается совершенно несвязанными результатами. У меня есть функция (шаблон), которая принимает pointer-to-member в качестве.

Рассмотрим следующий код: struct Foo < mutable int m; template void change_member() const < this->*member = 12; // Error: you cannot assign to a variable that is const >.

Компилируя на C++03, Я попытался написать тестовую шаблонную функцию, которая возвращает pointer-to-member-function функции-члена, которая возвращает int, и принимает два аргумента float.

struct MyStruct < typedef int MyStruct::*Ptr; // my pointer-to-member type int foo, bar; >; Этот код работает, но я хотел бы привести его up-to-date в современный стиль и заменить typedef на using .

Читать еще:  Размер фона для powerpoint

Using C++ Member Functions for C Function Pointers

The research department here at p-nand-q.com is pleased to announce another totally usefull study. not!

Understanding the problem

The consensus on the internet is that you cannot pass C++ member function pointers to functions expecting C function pointers.

For example, a typical question is How to pass a method to qsort?, and the answer marked as «correct» says you should provide the address of a static function. Clearly that is too easy: static class member functions are mostly the same as plain old C functions, so in a way that answer is simply cheating. Our computer scientists (well, there is only one of them, and he isn’t a really good scientist either) came up with an ingenious way for programmers to transcend classical logic and pass member functions.

Using C Function Pointers as C Function Pointers

Let’s work this through by using a time-honoured C function: qsort.

Assume you have some infrastructure that allows you to write the following:

If you want to sort that list with the C qsort function, you would traditionally have a C function and use it like the following:

OK, so far this is the classical solution. But you’re using a C function, and there is a rule in your contract that C functions get paid less than C++ functions, so you need to be seen passing a C++ method instead. What do you do?

Using Pointers to Static C++ Methods as C Function Pointers

Well, you declare the method as static. Example:

Well, this is the standard, boring answer you’d get if you asked regular people.

Using C++ Methods as C Function Pointers

But you’re unsatisfied with that solution. It is too easy. It is too readable. It doesn’t help you in securing a good job. You need more. And we are here to give it to you. We will show you how you can finally write code like this:

That is more like it. So how does it work?

How it works

Let’s start by doing a short recap of what we know. Take a look at the following declaration:

So, a C function pointer is a different type than a C++ member function pointer. When the compiler sees a C++ member function like this:

what it really does is create a C function like this:

It creates a hidden «this-pointer». This immediately explains why the two function pointers are not compatible: one points to a function receiving two args, the other to a function receiving three args. To put it another way: the caller of the function pointer will provide only two arguments, not three. (By the way: this also explains why static functions work: they have no object associated, so there is no hidden this-pointer generated, so their syntax looks the same). So what we need to do is this

  • We must provide the Caller with a compatible C function: a function of two arguments
  • In that function, we somehow must identify the missing «this»-Pointer and use that to call the member function pointer.

To put it yet another way: somehow, our function needs state.

Now, at this point an obvious solution can be seen: use global variables. Example:

However, this has a couple of problems:

  • It uses a global variable. It can point only to one object at any one time. You cannot have two separate functions (threads, cores) call the callback at the same time, because the global variable can have only one value
  • Really, what you would like to have is something like this:
    • Generate a function + global variable on the fly
    • Fill it with the value for a particular call

Enter templates. The basic idea is this: each template instantiation will create a different set of functions, including a different set of static functions.

At the core of our solution is a template very much like this:

When the compiler sees us using DynamicQSortCallback () , it will generate a function DynamicQSortCallback ::GeneratedStaticFunction , and when it sees us using DynamicQSortCallback () , it will generate a different function with a different context. This means the following holds true:

Armed with this information you should be able to come up with a solution on your own; but let’s walk slowly through the following anyway. We start off with the two obvious declarations shown above:

We need a class that holds the state of the C++ member function callback. It will do a couple of things in addition to this:

  • The class will represent a «slot» that can be allocated for use by a member function callback
  • The class gets a unique C callback for this «slot».
  • Slots can be «reserved» and «freed»

This is the code:

Next, we come up with a slight modification of our template shown above.

There are two important changes here:

  1. The class is derived from QsortCallbackBase , so it actually can be accessed like a slot.
  2. The constructor passes a pointer to the unique C function to the base data.

Now as for implementing the actual callback: let’s first look at the interface definition for it:

Essentially, this is a simple decorator class: the constructor maps the input — a C++ class pointer and a C++ member function pointer — and identifies the unique C callback function for it. The rest of the class is just «mechanics»: being able to call the function, checking if the mapping was successful.

Next, we create an array of up to 16 slots. That means, up to 16 functions can be using this technique either in parallel or recursive. Obviously, the number of slots is an implementation issue: you can easily use macros to provide space for much more allocations.

Now we begin putting it all together. The StaticInvoke used by our slot is simple: it has a context, it simply looks up the data for that context and invokes it:

The decorator class uses a standard RAII pattern to allocate / free the slot:

Built with Bootstrap | Valid HTML5 | Valid CSS3 | Impressum | Donations
Copyright © 2000. ∞ by Gerson Kurz. Generated on 14.12.2016 19:59:33.

C++: calling a member function pointer

This article is about calling a member function (method) through a “function pointer”. I decided to write about it because it tricked me for a while, and I think this may be useful to others.

I will start with a small introduction and gradually get to the point. If you’re really in a hurry scroll down to the end of the article to see how it’s done!

Calling a “global” function pointer

In good old C, the following code is probably familiar to most seasoned programmers:

void func1( void (*func)() ) <
func();
>

void func2() <
printf(«Goodbye world!n»);
>

Now if we compile this and execute it we’ll get of course the following output:

$ gcc fpointer.c
giannis@goofy:

$ ./a.out
Goodbye world!

The slightly strange syntax void (*func)() in func1()’s declaration, is what we call a “pointer to a function”. This one specifically declares that “func is pointer to a function with no arguments and no return value”.

Similarly, void (*func)(int) declares a pointer to a function that takes one int argument and returns no value, and int (*func)() declares a pointer to a function that takes no arguments and returns int.

Function pointers are like data pointers, except the point to executable code instead of data. It is pretty much a standard way in C to encapsulate and delegate behaviors or logic.

Now, let’s take the same scenario only this time within the scope of a C++ class. Consider this:

void func1( void (*func)() ) <
func();
>

void func2() <
printf(«Goodbye world!n»);
>

int main() <
MyClass myObject;
myObject.method();
>

At least for me, this made sense… But what happens if we try to compile?

$ g++ fpointer.cpp
fpointer.cpp: In member function void MyClass::method():
fpointer.cpp:19: error: no matching function for call to MyClass::func1( )
fpointer.cpp:8: note: candidates are: void MyClass::func1(void (*)())

What the error message says, more or less, is that that func1() expected to be called with an argument of type void (*)(), however we tried to pass an “unresolved overloaded function type”.

Читать еще:  Воспроизведение видео в powerpoint

Okay, that’s weird. func1() expects an argument of type void (*)(), and func2 was exactly of that type, right?

Well, not exactly. func2 is actually a MyClass::void (*)(), that is, it belongs to the MyClass namespace. On the other hand, func1() was expecting a void (*)(), which is a pointer to a function in the global scope/namespace (a “stray” function).

To fix this, we need to need to slightly modify the code in several few places.

First of all, the declaration of func1(). As we said the function will be called with an argument of type MyClass::void (*)(). Therefore it has to be altered accordingly:

void func1( void (MyClass::*func)() ) <
func();
>

Furthermore we need to change the way the function pointer is dereferenced inside func1(). It is not enough to just call func(). Remember that all the compiler knows is the address of a method, which remains the same for all instances of a class. When dereferencing a member function pointer, we also need to provide the object for whom the method is being called, in that case this holds a reference to this object, which is the one we aimed for. Thus, the func1()’s code becomes now:

void func1( void (MyClass::*func)() ) <
(*this.*func)();
>

The (*this.*func)(); statement just instructs the compiler to call the code of MyClass pointed by func, for this object.

And we’re almost done, we need to make one final small change, in the code that passes the member function pointer, so it makes clear that func2 is a method of MyClass and not a “stray” global function:

Now it should compile and work as expected:

$ g++ fpointer.cpp
giannis@goofy:

$ ./a.out
Goodbye world!

Let’s put it all together:

void func1( void (MyClass::*func)() ) <
(*this.*func)();
>

void func2() <
printf(«Goodbye world!n»);
>

Function Pointers in C and C++

Example Uses of Function Pointers

Functions as Arguments to Other Functions

If you were to write a sort routine, you might want to allow the function’s caller to choose the order in which the data is sorted; some programmers might need to sort the data in ascending order, others might prefer descending order while still others may want something similar to but not quite like one of those choices. One way to let your user specify what to do is to provide a flag as an argument to the function, but this is inflexible; the sort function allows only a fixed set of comparison types (e.g., ascending and descending).

A much nicer way of allowing the user to choose how to sort the data is simply to let the user pass in a function to the sort function. This function might take two pieces of data and perform a comparison on them. We’ll look at the syntax for this in a bit.

Callback Functions

Another use for function pointers is setting up «listener» or «callback» functions that are invoked when a particular event happens. The function is called, and this notifies your code that something of interest has taken place.

Why would you ever write code with callback functions? You often see it when writing code using someone’s library. One example is when you’re writing code for a graphical user interface (GUI). Most of the time, the user will interact with a loop that allows the mouse pointer to move and that redraws the interface. Sometimes, however, the user will click on a button or enter text into a field. These operations are «events» that may require a response that your program needs to handle. How can your code know what’s happening? Using Callback functions! The user’s click should cause the interface to call a function that you wrote to handle the event.

To get a sense for when you might do this, consider what might happen if you were using a GUI library that had a «create_button» function. It might take the location where a button should appear on the screen, the text of the button, and a function to call when the button is clicked. Assuming for the moment that C (and C++) had a generic «function pointer» type called function, this might look like this: Whenever the button is clicked, callback_func will be invoked. Exactly what callback_func does depends on the button; this is why allowing the create_button function to take a function pointer is useful.

Function Pointer Syntax

The syntax for declaring a function pointer might seem messy at first, but in most cases it’s really quite straight-forward once you understand what’s going on. Let’s look at a simple example: In this example, foo is a pointer to a function taking one argument, an integer, and that returns void. It’s as if you’re declaring a function called «*foo», which takes an int and returns void; now, if *foo is a function, then foo must be a pointer to a function. (Similarly, a declaration like int *x can be read as *x is an int, so x must be a pointer to an int.)

The key to writing the declaration for a function pointer is that you’re just writing out the declaration of a function but with (*func_name) where you’d normally just put func_name.

Reading Function Pointer Declarations

Initializing Function Pointers

Using a Function Pointer

Function Pointers in the Wild

Let’s go back to the sorting example where I suggested using a function pointer to write a generic sorting routine where the exact order could be specified by the programmer calling the sorting function. It turns out that the C function qsort does just that.

From the Linux man pages, we have the following declaration for qsort (from stdlib.h): Note the use of void*s to allow qsort to operate on any kind of data (in C++, you’d normally use templates for this task, but C++ also allows the use of void* pointers) because void* pointers can point to anything. Because we don’t know the size of the individual elements in a void* array, we must give qsort the number of elements, nmemb, of the array to be sorted, base, in addition to the standard requirement of giving the length, size, of the input.

But what we’re really interested in is the compar argument to qsort: it’s a function pointer that takes two void *s and returns an int. This allows anyone to specify how to sort the elements of the array base without having to write a specialized sorting algorithm. Note, also, that compar returns an int; the function pointed to should return -1 if the first argument is less than the second, 0 if they are equal, or 1 if the second is less than the first.

For instance, to sort an array of numbers in ascending order, we could write code like this:

Using Polymorphism and Virtual Functions Instead of Function Pointers (C++)

But Are You Really Not Using Function Pointers?

Function Pointers Summary

Syntax

Declaring

Initializing

Invoking

Benefits of Function Pointers

  • Function pointers provide a way of passing around instructions for how to do something
  • You can write flexible functions and libraries that allow the programmer to choose behavior by passing function pointers as arguments
  • This flexibility can also be achieved by using classes with virtual functions

I am grateful to Alex Hoffer and Thomas Carriero for their comments on a draft of this article.

C pointer to member function

Есть функция некоторого API, которая принимает в качестве аргумента указатель на свободную функцию. Ей необходимо передать нестатическую функцию-член.

Т.к. напрямую этого сделать нельзя (как известно, указатель на нестатическую функцию-член и указатель на свободную функцию — это абсолютно разные типы), я решил попробовать создать на основе возвращаемого функцией std::bind значения объект класса std::function, у которого вызвать функцию-член target.

В подобных случаях target возвращает nullptr. Это обсуждалось, например, в рассылке boost’а:

Читать еще:  Как изменить колонтитул в презентации powerpoint

Существует ли вообще нормальный способ преобразовать указатель на функцию-член в указатель на свободную функцию или нет? Предполагаю, что нет, но мало ли кто-нибудь придумал решение.

Здравствуйте, Nikita.Trophimov, Вы писали:

NT>Существует ли вообще нормальный способ преобразовать указатель на функцию-член в указатель на свободную функцию или нет? Предполагаю, что нет, но мало ли кто-нибудь придумал решение.

концептуально функция член ничего не умеет делать, если ей не передать this, поэтому предположу, что все же хочется сделать замыкание
эта проблема обсуждалась здесь: http://rsdn.ru/forum/cpp.applied/5114972.flat

Здравствуйте, Nikita.Trophimov, Вы писали:

NT>Есть функция некоторого API, которая принимает в качестве аргумента указатель на свободную функцию. Ей необходимо передать нестатическую функцию-член.

«this» ты откуда брать собрался?
Если this передаётся как аргумент этой «свободной» функции — то можно сделать простейший враппер:

Если же откуда-то из глобальной области тогда вот это:
live demo

Здравствуйте, Nikita.Trophimov, Вы писали:

NT>Есть функция некоторого API, которая принимает в качестве аргумента указатель на свободную функцию. Ей необходимо передать нестатическую функцию-член.
NT>.
NT>Существует ли вообще нормальный способ преобразовать указатель на функцию-член в указатель на свободную функцию или нет? Предполагаю, что нет, но мало ли кто-нибудь придумал решение.

В таких случаях хорошо, если в этом API предусмотрено передача в callback указателя на произвольный пользовательский контекст. В этом случае не сложно написать свою функцию-адаптер вокруг чего угодно и передать ее в качестве callback-а. Если же такой возможности не предусмотрено, то НОРМАЛЬНОГО способа использовать в качестве callback-ов функции члены и функциональные объекты не существует, извращений — сколько угодно. И остается только сказать «спасибо» за заботу разработчикам API.

Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>live demo
LWS был снова недоступен?

Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>Здравствуйте, Nikita.Trophimov, Вы писали:

NT>>Есть функция некоторого API, которая принимает в качестве аргумента указатель на свободную функцию. Ей необходимо передать нестатическую функцию-член.

EP>»this» ты откуда брать собрался?
EP>Если this передаётся как аргумент этой «свободной» функции — то можно сделать простейший враппер:
EP>
EP>Если же откуда-то из глобальной области тогда вот это:
EP>live demo
EP>

В таких случаях можно использовать __COUNTER__, а чтобы не было коллизий при линковке, заворачивать в анонимный неймспейс.

Здравствуйте, niXman, Вы писали:

EP>>live demo
X>LWS был снова недоступен?

Я этот код добавил давно. По ссылке:

148 days 14 hours ago

По поводу LWS (в продолжение темы из другого топика):
1. Я понял почему у меня «www.» было — это firefox сам добавлял. В итоге добавил закладку на панель, а то набираешь код, отправляешь — а он вылетает в трубу (потому «что www.»)
2. Проверил совсем старые коды — да, они доступны. Но почему-то мне запомнилось, что был период когда они были недоступны.
3. Я зарегистрировался пару недель назад на LWS, а письмо до сих пор не пришло.

Здравствуйте, saf_e, Вы писали:

_>В таких случаях можно использовать __COUNTER__, а чтобы не было коллизий при линковке, заворачивать в анонимный неймспейс.

Можно, но:
1. Это придётся весь вызов заворачивать в макрос (конечно не обязательно)
2. Пропадёт возможность реиспользования слота (может быть существенно, если объекты большие)
3. имхо, для примера — лучше явно показать что происходит, чтобы были видны грабли по поводу коллизий

Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>Здравствуйте, saf_e, Вы писали:

_>>В таких случаях можно использовать __COUNTER__, а чтобы не было коллизий при линковке, заворачивать в анонимный неймспейс.

EP>Можно, но:
EP>1. Это придётся весь вызов заворачивать в макрос (конечно не обязательно)
EP>2. Пропадёт возможность реиспользования слота (может быть существенно, если объекты большие)
EP>3. имхо, для примера — лучше явно показать что происходит, чтобы были видны грабли по поводу коллизий

Как мне что-то подсказывает самый частый юз-кейс как раз использование уникальный слотов.

Просто я упомянул про способ облегчить себе жизнь (особенно если по файлу беспорядочно раскиданы выделения слотов). Ну а про коллизию имело смысл упомянуть, она не очевидна, а сайд-эффект весьма интересен

Здравствуйте, saf_e, Вы писали:

_>Как мне что-то подсказывает самый частый юз-кейс как раз использование уникальный слотов.
_>Просто я упомянул про способ облегчить себе жизнь (особенно если по файлу беспорядочно раскиданы выделения слотов).

Ничего против счётчика не имею. Во время написания ответа даже подумал об шаблонном счётчике

(без макросов, основанный на implementation specific extensions/bugs).

_>Ну а про коллизию имело смысл упомянуть, она не очевидна, а сайд-эффект весьма интересен

Кстати, другой подход:
1. аллоцировать пул функций при старте (например с помощью boost::mpl::for_each)
2. get_wrapper всегда будет возвращать следующую функцию из пула. если больше нет — то termintate или exception.

Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>Здравствуйте, saf_e, Вы писали:

_>>Как мне что-то подсказывает самый частый юз-кейс как раз использование уникальный слотов.
_>>Просто я упомянул про способ облегчить себе жизнь (особенно если по файлу беспорядочно раскиданы выделения слотов).

EP>Ничего против счётчика не имею. Во время написания ответа даже подумал об шаблонном счётчике

(без макросов, основанный на implementation specific extensions/bugs).

Спасибо, любопытно, при попытке разобраться в тимплейтах мозг закипает

_>>Ну а про коллизию имело смысл упомянуть, она не очевидна, а сайд-эффект весьма интересен

EP>Кстати, другой подход:
EP>1. аллоцировать пул функций при старте (например с помощью boost::mpl::for_each)
EP>2. get_wrapper всегда будет возвращать следующую функцию из пула. если больше нет — то termintate или exception.

Сомнительное удовольствие

Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>Я этот код добавил давно. По ссылке:
EP>

EP>148 days 14 hours ago

да, я не обратил внимания.

EP>1. Я понял почему у меня «www.» было — это firefox сам добавлял. В итоге добавил закладку на панель, а то набираешь код, отправляешь — а он вылетает в трубу (потому «что www.»)
жесть %)
погуглю, что можно сделать с этим. возможно, в htaccess или в конфиге апатча что-то можно подкрутить.

EP>2. Проверил совсем старые коды — да, они доступны. Но почему-то мне запомнилось, что был период когда они были недоступны.
после запуска новой версии, был период, пока я перенес коды с прежней версии сервиса.

EP>3. Я зарегистрировался пару недель назад на LWS, а письмо до сих пор не пришло.
если гуглопочта, то она почему-то(при том, не всегда) кидает письмо активации в спам. хотя, адрес отправителя никогда ранее не использовался. я на нескольких форумах спрашивал, от чего такое может происходить. ничего вразумительного в ответ.
если письмо в спаме таки найдешь — срок его валидности все равно истек. в этом случае, напиши мне в ЛС и сообщи ник+почту, я активирую.

Здравствуйте, Nikita.Trophimov, Вы писали:

NT>Существует ли вообще нормальный способ преобразовать указатель на функцию-член в указатель на свободную функцию или нет? Предполагаю, что нет, но мало ли кто-нибудь придумал решение.

Здравствуйте, niXman, Вы писали:

EP>>1. Я понял почему у меня «www.» было — это firefox сам добавлял. В итоге добавил закладку на панель, а то набираешь код, отправляешь — а он вылетает в трубу (потому «что www.»)
X>жесть %)

вот я ввожу live, он дополняет до liveworkspace.org/ , нажимаю Enter и ссылка превращается в http://www.liveworkspace.org/
Если убрать «выделение автодополнения» либо ввести полностью http://liveworkspace.org — то без www.

X>погуглю, что можно сделать с этим. возможно, в htaccess или в конфиге апатча что-то можно подкрутить.

да, можно попробовать поставить редирект у www

EP>>3. Я зарегистрировался пару недель назад на LWS, а письмо до сих пор не пришло.
X>если гуглопочта, то она почему-то(при том, не всегда) кидает письмо активации в спам. хотя, адрес отправителя никогда ранее не использовался. я на нескольких форумах спрашивал, от чего такое может происходить. ничего вразумительного в ответ.
X>если письмо в спаме таки найдешь — срок его валидности все равно истек. в этом случае, напиши мне в ЛС и сообщи ник+почту, я активирую.

Да, именно в спаме и было, причём только в веб-интерфейсе (а я thunderbird использую). Надо настроить отдачу спама в imap/pop3 — а то вдруг что важное.
Письмо пришло 13 дней назад — только что активировал, всё ОК.

P.S. Кстати, в спаме ещё было нигерийское письмо

Ссылка на основную публикацию
Adblock
detector