Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
212 views
in Technique[技术] by (71.8m points)

c++ - Using `std::function<void(...)>` to call non-void function

A while ago I used std::function pretty much like this:

std::function<void(int)> func = [](int i) -> int { return i; };

Basically, I did this because I wanted to store different function objects in a std::function, but I didn't want to restrict the return types of these functions. Since this seemed to work, I went with it. But I'm not convinced that it is safe to use, and I haven't been able to find any documentation on it. Does anyone know whether this usage is legitimate? Or more generally, what the rules are for the object which can safely be assigned to a std::function?

Edit

For clarification, the issue I'm concerned with is that the lambda function returns an int, while func is declared with return type void. I'm not sure if this is OK, especially once a call to func() is made.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Your code has undefined behavior. It may or may not work as you expect. The reason it has undefined behavior is because of 20.8.11.2.1 [func.wrap.func.con]/p7:

Requires: F shall be CopyConstructible. f shall be Callable (20.8.11.2) for argument types ArgTypes and return type R.

For f to be Callable for return type R, f must return something implicitly convertible to the return type of the std::function (void in your case). And int is not implicitly convertible to void.

I would expect your code to work on most implementations. However on at least one implementation (libc++), it fails to compile:

test.cpp:7:30: error: no viable conversion from 'int (int)' to 'std::function<void (int)>'
    std::function<void(int)> ff = f;
                             ^    ~

Ironically the rationale for this behavior stems from another SO question.

The other question presented a problem with std::function usage. The solution to that problem involved having the implementation enforce the Requires: clause at compile time. In contrast, the solution to this question's problem is forbidding the implementation from enforcing the Requires: clause.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...