std::initializer_list with Multiple Types - c++11

I'm having trouble with std::initializer_list. I reduced it down to a simple example:
#include <initializer_list>
#include <cstdio>
class Test {
public:
template <typename type> Test(const std::initializer_list<type>& args) {}
};
int main(int argc, char* argv[]) {
Test({1,2});
getchar();
return 0;
}
When compiled using g++ test_initializer.cpp -std=c++0x, it compiles and runs well. However, if line 11 is changed to Test({1,2.0});, one gets:
ian#<host>:~/Desktop$ g++ test_initializer.cpp -std=c++0x
test_initializer.cpp: In function ‘int main(int, char**)’:
test_initializer.cpp:11:14: error: no matching function for call to ‘Test::Test(<brace-enclosed initializer list>)’
test_initializer.cpp:11:14: note: candidates are:
test_initializer.cpp:7:28: note: template<class type> Test::Test(const std::initializer_list<_Tp>&)
test_initializer.cpp:5:7: note: constexpr Test::Test(const Test&)
test_initializer.cpp:5:7: note: no known conversion for argument 1 from ‘<brace-enclosed initializer list>’ to ‘const Test&’
test_initializer.cpp:5:7: note: constexpr Test::Test(Test&&)
test_initializer.cpp:5:7: note: no known conversion for argument 1 from ‘<brace-enclosed initializer list>’ to ‘Test&&’
I suspect this happens because the compiler can't figure out what type to make the initializer list. Is there a way to fix the example so that it works with different types (and still uses initializer lists)?

An std::initializer_list takes only one type. If you need different types, you can use variadic templates:
template<typename... Args>
Test(Args&&... args);
/* ... */
int main()
{
Test(1, 2.0);
}

Would a std::tuple<int.double> work for the OP? If the code will always have a int followed by a double, then the OP could get strict type-checking for all arguments, which the variable arguments solution does not allow. The std::tuple<>, however, would not work for any number or order of values, so may not be appropriate for all use cases.

Let the initializer_list hold the most arbitrary pointers, void*, and do your own casting from there. Here is an example.
#include <initializer_list>
#include <iostream>
using std::initializer_list;
using std::cout;
using std::endl;
class Person {
private:
string _name;
int _age;
public:
Person(initializer_list<void*> init_list) {
auto it = init_list.begin();
_name = *((string*)(*it));
it++;
_age = *((int*)(*it));
}
void print() {
cout << "name: " << _name << ". age: " << _age << endl;
}
};
int main(void) {
string name{"Vanderbutenburg};
int age{23};
Person p{&name,&age};
p.print(); // "name: Vanderbutenburg. age: 23"
return 0;
}

Related

error: no matching constructor for initialization of 'std::thread' issue in forwarding function pointer to thread

I am facing an issue in forwarding a callable object (function pointer) to a
thread.
Here is an example code trying achieve.
#include <iostream>
#include <thread>
using namespace std;
void my_func(int x, int y, int z){
cout << "X: " << x << "\tY: " << y << "\tZ "<<z << endl;
}
template <typename T, typename ... Args>
void my_thread(T func, Args&&... args){
// Do something
func(forward<Args&&>(args)...);
}
template <typename T, typename ... Args>
void call_thread(T func, Args&& ... args){
// Do something
thread t1(my_thread, func, forward<Args&&>(args)...);
t1.detach();
}
int main()
{
call_thread(my_func, 2,5,6);
return 0;
}
Error:
In instantiation of 'void call_thread(T, Args&& ...) [with T = void (*)(int, int, int); Args = {int, int, int}]':
required from here
error: no matching function for call to 'std::thread::thread(<unresolved overloaded function type>, void (*&)(int, int, int), int, int, int)'
thread t1(my_thread, func, forward<Args&&>(args)...);
^
In the declaration statement
thread t1(my_thread, func, forward<Args&&>(args)...);
since my_thread is the name of a function template, it's essentially a large set of different functions. But to instantiate the std::thread constructor and create the std::thread, the compiler needs to choose just one specialization of my_thread and the std::thread constructor. Since the thread constructor is set up to take any callable type at all as the first argument, there isn't a direct relationship between the callable and the arguments that would help force that into one type, and the compiler can't figure it out on its own.
So specify the correct my_thread specialization:
thread t1(my_thread<T, Args...>, func, forward<Args&&>(args)...);
IMHO, it's not a good idea to initialize std::thread in a function where it goes out of scope immediately. It's better to keep track of the std::thread object. Anyway, your my_thread() function seems unnecessary to me, since call_thread() does the calling of a thread function which is passed into it (func). Below code works when compiled with -lpthread on Arch Linux x86_64:
#include <iostream>
#include <thread>
#include <utility>
using namespace std::chrono_literals;
void my_func(int x, int y, int z){
std::cout << "X: " << x << "\tY: " << y << "\tZ "<<z << std::endl;
}
template <typename T, typename ... Args>
void call_thread(T&& func, Args&& ... args) {
// Do something
std::thread t1(std::forward<T>(func), std::forward<Args>(args)...);
t1.detach();
}
int main() {
call_thread(my_func, 2, 5, 6);
std::this_thread::sleep_for(5s);
return 0;
}
By the way, you need the thread sleep at the end; otherwise your program will reach to return 0 and exit, before my_func() prints out the values!

Different behavior of Visual Studio and gcc when compiling variadic templates program

I'm playing with C++11's variadic templates, and here is my code:
#include "iostream"
void func(){
std::cout << std::endl;
}
template< typename ...Params> void func(int x, Params... params){
std::cout << " int " << x;
func(params...);
}
template< typename ...Params> void func(float x, Params... params){
std::cout << " float " << x;
func(params...);
}
template< typename ...Params> void func(const char* x, Params... params){
std::cout << " const char* " << x;
func(params...);
}
int main(int argc, char* argv[])
{
func(3.14f, 5, "Test");
getchar();
return 0;
}
The code above can be compiled and run on Visual Studio 2013 without any problem, but if I compile it with gcc 4.6.3 (I don't have gcc environment and using online service like repl.it), this code will produce error like this:
main.cpp: In instantiation of 'void func(int, Params ...) [with Params = {const char*}]':
main.cpp:15:6: required from 'void func(float, Params ...) [with Params = {int, const char*}]'
main.cpp:24:23: required from here
main.cpp:11:6: error: no matching function for call to 'func(const char*&)'
func(params...);
~~~~^~~~~~~~~~~
main.cpp:5:6: note: candidate: void func()
void func(){
^~~~
main.cpp:5:6: note: candidate expects 0 arguments, 1 provided
main.cpp:9:36: note: candidate: template<class ... Params> void func(int, Params ...)
template< typename ...Params> void func(int x, Params... params){
^~~~
main.cpp:9:36: note: template argument deduction/substitution failed:
main.cpp:11:6: note: cannot convert 'params#0' (type 'const char*') to type 'int'
func(params...);
~~~~^~~~~~~~~~~
exit status 1
Whose behavior is right? Is this code has some problem I don't acknowledge or this is a bug of gcc?
BTW: If I change func(3.14f,5,"test") into func(3.14f,5) then gcc can compile this code as well.
gcc behaviour is right.
Roughly speaking, when you instantiate a template, the instantiation needs to be legal C++ code when placed where the original template definition was found. (More precisely, all names except so-called dependent names need to be resolvable at the point of template definition).
In your case, the first template instantiates to an equivalent of
void func(int x, const char *params0){
std::cout << " int " << x;
func(params0);
}
and the last call is not valid at the point of template definition. Indeed, the template that can handle the call does not get declared until later in the code.
VC++ is known for its non-compliant handling of templates: it only checks validity of the instantiation at the point of instantiation, not at the point of the original template definition. This code illustrates it nicely.
To bring your code to compliance, first forward-declare the templates and then define them.

How can I use Boost.Hana to determine whether a functor has a call operator that can be invoked with a particular template argument?

In my application, I want to determine at compile time whether an arbitrary functor type Func has a nullary call operator that can be invoked with a given explicit template argument T. Based on a previous SO answer that I found, I came up with the following:
#include <boost/hana.hpp>
#include <iostream>
#include <type_traits>
namespace hana = boost::hana;
namespace detail
{
template <typename T>
auto can_call = hana::is_valid([](auto &&f) ->
decltype(f.template operator()<T>()) { });
}
template <typename Func, typename T>
constexpr auto can_call() ->
decltype(detail::can_call<typename std::remove_reference<T>::type>(
std::declval<Func>())) { return {}; }
struct foo
{
template <typename T, typename =
std::enable_if_t<!std::is_same<T, char>::value>>
void operator()() const { }
};
int main()
{
std::cout << "char: " << can_call<foo, char>() << std::endl;
std::cout << "int: " << can_call<foo, int>() << std::endl;
}
I would expect this example to print out:
char: 0
int: 1
Since the char template argument type is explicitly enable_if-ed out in foo. I've tried the following compilers:
Apple clang v8.0.0: The example compiles and runs as expected.
mainline clang v3.9.1+ (via Wandbox): The example compiles and runs as expected.
mainline clang v3.6.0 - v3.8.1 (via Wandbox): The compiler dies with an internal error.
g++ 7.0 trunk, 20170410 (via Wandbox): The compilation fails with the following errors:
dd.cc: In instantiation of ‘auto detail::can_call<char>’:
dd.cc:15:14: required by substitution of ‘template<class Func, class T> constexpr decltype (can_call<typename std::remove_reference<_To>::type>(declval<Func>())) can_call() [with Func = foo; T = char]’
dd.cc:25:50: required from here
dd.cc:10:10: error: ‘auto detail::can_call<char>’ has incomplete type
auto can_call = hana::is_valid([](auto &&f) -> decltype(f.template operator()<T>()) { });
^~~~~~~~
dd.cc: In function ‘int main()’:
dd.cc:25:50: error: no matching function for call to ‘can_call<foo, char>()’
std::cout << "char: " << can_call<foo, char>() << std::endl;
^
dd.cc:14:16: note: candidate: template<class Func, class T> constexpr decltype (can_call<typename std::remove_reference<_To>::type>(declval<Func>())) can_call()
constexpr auto can_call() ->
^~~~~~~~
dd.cc:14:16: note: substitution of deduced template arguments resulted in errors seen above
dd.cc: In instantiation of ‘auto detail::can_call<int>’:
dd.cc:15:14: required by substitution of ‘template<class Func, class T> constexpr decltype (can_call<typename std::remove_reference<_To>::type>(declval<Func>())) can_call() [with Func = foo; T = int]’
dd.cc:26:48: required from here
dd.cc:10:10: error: ‘auto detail::can_call<int>’ has incomplete type
auto can_call = hana::is_valid([](auto &&f) -> decltype(f.template operator()<T>()) { });
^~~~~~~~
dd.cc:26:48: error: no matching function for call to ‘can_call<foo, int>()’
std::cout << "int: " << can_call<foo, int>() << std::endl;
^
dd.cc:14:16: note: candidate: template<class Func, class T> constexpr decltype (can_call<typename std::remove_reference<_To>::type>(declval<Func>())) can_call()
constexpr auto can_call() ->
^~~~~~~~
dd.cc:14:16: note: substitution of deduced template arguments resulted in errors seen above
It seems to not like my use of hana::is_valid() to determine whether the specified operator exists. However, I think the way I'm using it is consistent with its intended use.
Is this a bug in gcc, a more lenient implementation in contemporary clang versions, or did I implement this type of check incorrectly? It seems like this is definitely within Hana's wheelhouse; I'm just trying to wrap my head around its new model of constexpr metaprogramming.
Here is a workaround that uses a struct "functor" instead of a lambda and an extra layer of indirection for the type of the is_valid instance to appease gcc.
namespace detail
{
template <typename T>
struct check_can_call {
template <typename F>
constexpr auto operator()(F&& f) ->
decltype(f.template operator()<T>()) { }
};
template <typename T>
using is_call_valid = decltype(hana::is_valid(check_can_call<T>{}));
template <typename T>
constexpr is_call_valid<T> can_call{};
}

Expanding a lambda for each parameter of a parameter pack: Clang vs. GCC

This code works fine in Clang 3.5:
#include <iostream>
#include <string>
void callFuncs() {}
template<typename Func, typename ...Funcs>
void callFuncs(const Func &func, const Funcs &...funcs)
{
func();
callFuncs(funcs...);
}
template<typename ...Types>
void callPrintFuncs()
{
callFuncs(([] { std::cout << Types() << std::endl; })...);
}
int main()
{
callPrintFuncs<int, float, double, std::string>();
}
However, in GCC 4.9, I get the following error instead:
test.cpp: In lambda function:
test.cpp:16:54: error: parameter packs not expanded with '...':
callFuncs(([] { std::cout << Types() << std::endl; })...);
^
test.cpp:16:54: note: 'Types'
test.cpp: In function 'void callPrintFuncs()':
test.cpp:16:58: error: expansion pattern '<lambda>' contains no argument packs
callFuncs(([] { std::cout << Types() << std::endl; })...);
So, which compiler has a bug, Clang or GCC? The Clang behavior makes the most sense to me at least.
gcc is broken here. There are rules against unexpanded parameter packs in the standard, but the above parameter pack is expanded.
It is expanded after the end of innermost statement it is in, but the standard does not require that the parameter packs be expanded by the end of every statement.
The fact that gcc got it wrong is sort of understandable; naively, you'd think that a parameter pack can only be within one statement, and the failure to expand at the end of the statement is fatal. But lambdas let you nest statements within statements.
A general workaround can be to pass in one lambda and pass in a "tag" type to it.
template<class T>struct tag_t{using type=T;};
template<class Tag>using type_t=typename Tag::type;
template<typename Func, typename ...Ts>
void callOnEachOf(Func&&func, Ts&&...ts)
{
using discard=int[];
(void)discard{0,((void)(
func(std::forward<Ts>(ts))
),0)...};
}
template<typename ...Types>
void callPrintFuncs()
{
callOnEachOf(
[](auto tag){
using Type=type_t<decltype(tag)>;
std::cout << Type() << std::endl;
},
tag_t<Types>...
);
}

How to store functional objects with different signatures in modern C++

I would like to know if there is a way to store functional objects (functions, callbacks, ...) with different signatures in a standard container (std::map) with modern C++ only. The library that manages the container does not know which signatures will be used by its "clients".
My need is the same as exposed here : How to store functional objects with different signatures in a container?, and this solution https://stackoverflow.com/a/8304873/4042960 is about perfect for me: I would just like to do the same thing without boost. As far as I know, there is no std::any. The best solution for me would be to store std::function without specialized them, but I do not know how to do it, if it is possible.
Edit:
With the answers you give to me I wrote this example :
#include <map>
#include <memory>
#include <functional>
#include <string>
#include <iostream>
#include <stdexcept>
class FunctionMap
{
struct Base {
virtual ~Base() {}
};
template<class R, class... Args>
struct Func : Base
{
std::function<R(Args...)> f;
};
std::map<std::string, std::shared_ptr<Base> > _map;
public:
template<class R, class... Args>
void store(const std::string &key, const std::function<R(Args...)> &f) {
auto pfunc = std::make_shared<Func<R, Args...> >();
pfunc->f = f;
_map.insert(std::make_pair(key, pfunc));
}
template<class R, class... Args>
std::function<R(Args...)> get(const std::string &key) {
auto pfunc = std::dynamic_pointer_cast<Func<R, Args...> >(_map[key]);
if (pfunc)
return pfunc->f;
else
throw std::runtime_error("Bad type for function's parameters");
}
};
// test
int plus(int a, int b) { return a+b; }
double multiplies(double x, double y) { return x*y; }
int main()
{
FunctionMap fm;
fm.store("plus", std::function<int(int, int)>(&plus));
fm.store("multiplies", std::function<double(double, double)>(&multiplies));
// fm.store("square", std::bind(&multiplies, std::placeholders::_1, std::placeholders::_1));
std::cout << "5 + 3 = " << fm.get<int, int, int>("plus")(5, 3) << std::endl;
std::cout << "5 * 3 = " << fm.get<double, double, double>("multiplies")(5.0, 3.0) << std::endl;
return 0;
}
This works well, but I would like to improve it a bit:
1) I would like to be able to use std::bind : fm.store("square", std::bind(&multiplies, std::placeholders::_1, std::placeholders::_1)); but currently that does not compile ;
2) I would like to use fm.get<int (int, int)>("plus") instead of fm.get<int, int, int>("plus") but I do not know how to do it.
Many thanks for your help !
You can write your own any. Without all the compiler workarounds and stuff, boost::any can be written in about 30 lines of code.
Function objects are in no way different from any other kind of objects, so anything applicable to objects in general is applicable to function objects.
So you want to store different kinds of (function) objects in a map. This is normally done by storing (smart) pointers to a base class, where each derived class holds its own kind of objects you want to store.
struct Base {
virtual ~Base(){}
};
template <typename A>
struct Object : Base {
A value;
};
That's your basic caveman's boost::any. Your clients do something like this:
Base* b = mymap["foo"];
dynamic_cast<Object<void(*)(int)>*>(b)->val(123);
But with appropriate checks of course.

Resources