MSVC2013 and variadic template methods with std::thread compilation error - c++11

I have a threads manager class with the folloing methods:
template <class _Fn, class... _Args>
void create_thread (_Fn&& fun, _Args&&... args)
{
std::thread t (std::mem_fn(&MyClass::threads_entry<_Fn, _Args...>),
this, fun, args...);
}
template <class _Fn, class... _Args>
void threads_entry (_Fn&& fun, _Args&&... args)
{
fun (std::forward <_Args>(args)...);
perform_on_before_thread_exit_tasks();
}
In another class I'm trying to use it. This class has the following members:
void make_sure_thread_created ()
{
m_threads.create_thread (
&MyClass2::thread_tasks,
this);
}
void thread_tasks ()
{
}
I get compilation error (MS VC2013):
error: C2064: term does not evaluate to a function taking 1 arguments
It points to this line of code:
fun (std::forward <_Args>(args)...);
Am I doing something wrong? Or is it the compiler bug? What can be done here?...

It seems it's a bug of both VC2013 and VC2015 compilers.
Workaround:
m_threads.create_thread (
std::bind (&MyClass2::thread_tasks, std::placeholders::_1),
this);

Related

C++11 Call virtual member function

I`m trying to implement something like this using C++11.
class Proto{
public:
virtual void fu() = 0;
};
class Impl: public Proto{
public:
void fu();
};
void Impl::fu(){
LOG_INFO("im fu");
}
class Inv{
public:
void useFu(void (Proto::*)());
};
void Inv::useFu(void (Proto::*fu)()){
//fu();
};
void main(){
Impl impl;
Inv inv;
//inv.useFu(impl.fu);
}
useFu(void (Proto::*)()) must be declared in this way because, fu() uses some specific to Proto functionality's
I have two places were things going wrong.
First is fu() call itself and second how to pass fu as parameter inv.useFu(impl.fu).
Edit after bipll answer
The suggested usage of inv.useFu() solves the second problem of my question.
inv.useFu(static_cast<void (Proto::*)(void)>(&Impl::fu));
But I still need to call fu as a pointer to member function;
The way your useFu is declared now, it should be called as
inv.useFu(static_cast<void (Proto::*)(void)>(&Impl::fu));
But I guess that's not what you wanted. It should rather be
template<class F> void useFu(F &&f) { std::invoke(std::forward<F>(f)); }
or simply
void useFu(std::function<void()> f) { std::invoke(std::move(f)); }
and called as
useFu([&]{ impl.fu(); });
(Rather than using a lambda you can bind the method to the object with std::bind in the latter call but almost nobody ever does that.)

How to use a templated google benchmark fixture with custom arguments correctly?

I want to modify a templated google benchmark (with custom arguments) to run with a test fixture class, but don't know if this is really possible and if so, how the correct syntax is.
Just adding the fixture class doesn't seem to be enough.
static void CustomArguments(benchmark::internal::Benchmark* b) {
// define I, J
for (auto i : I)
{
for (auto j : J)
b->Args({i, j});
}
}
template<typename my_type>
class My_Fixture : public benchmark::Fixture
{
protected:
void SetUp(const ::benchmark::State& state) { ...}
virtual void TearDown() { ...}
};
template <typename any_type>
static void insert(benchmark::State& state)
{
for (auto _ : state)
{ ...}
}
BENCHMARK_TEMPLATE_F(My_Fixture, insert, my_type)->Apply(CustomArguments);
BENCHMARK_MAIN();
The compiler complains about the before-last code line
error: expected initializer before '->' token, but also fails to find the variable declarations from the fixture inside the test. This might be a consequence or an additional error. Do I need to register the fixture additionally? The example is running perfectly without fixture.
You'll need to use a slightly less convenient registration macro:
BENCHMARK_TEMPLATE_DEFINE_F defines the templated benchmark with the fixture. Then BENCHMARK_REGISTER_F can be used to register the benchmark, and that is where you'd add the ->Apply(CustomArguments) call.
See here for an example.

What's the right way to call static_assert(false)?

I’m trying to use static_assert to force something to fail. If you try to instantiate a specific templated function in a specific way I want to generate a complier error. I could make it work, but it was really ugly. Is there an easier way to do this?
This was my first attempt. This did not work at all. It always generates an error, even if no one tries to use this function.
template< class T >
void marshal(std::string name, T *value)
{
static_assert(false, "You cannot marshal a pointer.");
}
Here’s my second attempt. It actually works. If you don’t call this, you get no error. If you do call this, you get a very readable error message that points to this line and points to the code that tried to instantiate it.
template< class T >
void marshal(std::string name, T *value)
{
static_assert(std::is_pod<T>::value && !std::is_pod<T>::value, "You cannot marshal a pointer.");
}
The problem is that this code is ugly at best. It looks like a hack. I’m afraid the next time I change the optimization level, upgrade my compiler, sneeze, etc, the compiler will realize that this second case is the same as the first, and they will both stop working.
Is there a better way to do what I’m trying to do?
Here’s some context. I want to have several different versions of marshal() which work for different input types. I want one version that uses a template as the default case. I want another one that specifically disallows any pointers except char *.
void marshal(std::string name, std::string)
{
std::cout<<name<<" is a std::string type."<<std::endl;
}
void marshal(std::string name, char *string)
{
marshal(name, std::string(string));
}
void marshal(std::string name, char const *string)
{
marshal(name, std::string(string));
}
template< class T >
void marshal(std::string name, T value)
{
typedef typename std::enable_if<std::is_pod<T>::value>::type OnlyAllowPOD;
std::cout<<name<<" is a POD type."<<std::endl;
}
template< class T >
void marshal(std::string name, T *value)
{
static_assert(false, "You cannot marshal a pointer.");
}
int main (int argc, char **argv)
{
marshal(“should be pod”, argc);
marshal(“should fail to compile”, argv);
marshal(“should fail to compile”, &argc);
marshal(“should be std::string”, argv[0]);
}
There is no way to do this. You might be able to make it work on your compiler, but the resulting program is ill formed no diagnostic required.
Use =delete.
template< class T >
void marshal(std::string name, T *value) = delete;
What you are trying to do is doomed to be ill-formed (even your workaround can fail) according to [temp.res]/8 (emphasis mine):
Knowing which names are type names allows the syntax of every template
to be checked. The program is ill-formed, no diagnostic required, if:
- no valid specialization can be generated for a template or a substatement of a constexpr if statement within a template and the
template is not instantiated, or (...)
Relying on a contradiction is not the best indeed, but there's a simpler way:
template <class...>
struct False : std::bool_constant<false> { };
template <class T>
void bang() {
static_assert(False<T>{}, "bang!");
}
Why does this not fall under the "no valid specialization" case?
Well, because you can actually make a valid specialization, with that second half of the code:
template <>
struct False<int> : std::bool_constant<true> { };
int main() {
bang<int>(); // No "bang"!
}
Of course, no one is actually going to specialize False to break your assertions in real code, but it is possible :)
I don't understand why you have template< class T > void marshal(std::string name, T *value) in the first place. This should just be a static_assert in the primary template.
That is, you should change the definition of your primary template to
template< class T >
void marshal(std::string name, T value)
{
static_assert(std::is_pod<T>::value);
static_assert(!std::is_pointer<T>::value);
std::cout<<name<<" is a POD type."<<std::endl;
}

C++/CLI Compilation error with generic delegate

I'm currently doing some work with C++/CLI, and am encountering a strange compilation error with the following code:
private ref class LinqHelper abstract sealed
{
public:
generic<typename T, typename U> static Func<T, U>^ Cast()
{
return gcnew Func<T, U>(&LinqHelper::Cast);
}
private:
generic<typename T, typename U> static U Cast(T val)
{
return safe_cast<U>(val);
}
};
error C3352: 'Cast' : the specified function does not match the delegate type 'U (T)'
To be more specific, the problematic line of code is:
return gcnew Func<T, U>(&LinqHelper::Cast);
I find myself at a loss to explain this error. The Cast static member function that I am passing to the Func delegate constructor has the required signature, i.e. U Cast(T val).
Could anyone help shed some light on this for me please?
If it is of any help: i am working with VS 2015 and the C++/CLI project is referencing the .NET framework v4.5.2.
Thank you
The compiler is not happy about having to infer the type arguments for the Cast method. Lousy error message, not uncommon in C++/CLI. Fix:
return gcnew Func<T, U>(&LinqHelper::Cast<T, U>);

Exceptions w/QtConcurrent::Exception and boost::exception

I want to use an exception hierarchy where the base exception class derives from boost::exception so that I can get the nice and useful diagnostic information that that class has to offer and QtConcurrent::Exception so that I can throw my exceptions across threads.
Hence, my base exception class looks like:
class MyException : public QtConcurrent::Exception, public boost::exception
{
public:
MyException() { };
virtual ~MyException() throw() { }
// required by QtConcurrent::Exception to be implemented
virtual void raise() const { throw *this; }
virtual MyException* clone() const { return new MyException(*this); }
};
Per QtConcurrent::Exception's documentation, raise() and clone() must be implemented in any class derived from QtConcurrent::Exception. So, the rest of my code may look something like:
void foo()
{
BOOST_THROW_EXCEPTION(MyException());
}
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
try
{
foo();
}
catch (const MyException& me)
{
std::cerr << boost::diagnostic_information(me);
}
return 0;
}
However, using the BOOST_THROW_EXCEPTION() macro causes the following compilation error:
error C2555: 'boost::exception_detail::clone_impl::clone':
overriding virtual function return type differs and is not covariant
from 'MyException::clone'
I am not entirely sure what this error is telling me (my fault, not the errors, I'm sure!).
If I instead use throw MyException(); the code compiles just fine. As I mentioned above, I'd like to use BOOST_THROW_EXCEPTION() so that I get the diagnostic information in my exceptions.
I know that one possible work-around could be another class derived from just QtConcurrent::Exception that has a boost::exception member, essentially a container for the actual error. But if possible, I would like to continue to have the MyException class inherit from both QtConcurrent::Exception and boost::exception.
Can someone offer some insight into what the error is saying? Is there any way to accomplish what I want?

Resources