I'm working with Visual Studio 2012 on Windows 8 and trying to create a wrapper for std::queue which adds thread safety and a few other features. I'm having trouble creating a wrapper function for emplace. I suspect it's due to the way variadic templates are emulated, but I"m not sure how to fix it.
template <typename T>
class MyQueue
{
public:
template <class... Args> // line 20
void emplace(Args&&... args)
{
mQueue.emplace(std::forward<Args>(args)...);
}
private:
std::queue<T> mQueue;
};
This code gives me a bunch of syntax errors.
# line 20:
C2011: '' : 'enum' type redefinition
C2143: syntax error : missing ',' before '...'
C2332: 'class' : missing tag name
# line 21:
C2059: syntax error : '...'
C2065: 'Args' : undeclared identifier
Is there any clean way to tap into the underlying queue's emplace function? I'm not doing anything performance critical so if it ends up being more trouble than it's worth I'll just force callers to use push.
Any solutions must be with VC++11 - switching platforms or compilers is not an option for me.
I ended up getting this to work by changing the Platform Toolset to the Nov 2012 CTP in the project settings. As others pointed out - the code itself was correct. See below for a simple example.
MyQueue.h:
#pragma once
#include <queue>
template <typename T>
class MyQueue
{
public:
template <class... Args>
void emplace(Args&&... args);
private:
std::queue<T> mQueue;
};
template <typename T>
template <class... Args>
void MyQueue<T>::emplace(Args&&... args)
{
mQueue.emplace(std::forward<Args>(args)...);
}
Main.cpp
#include "MyQueue.h"
struct Test
{
int mA, mB;
Test(int a, int b) : mA(a), mB(b) { }
};
int main()
{
MyQueue<Test> q;
q.emplace(1, 1);
q.emplace(2, 2);
q.emplace(3, 3);
return 0;
}
Related
The code like this:
template<class hostClassType, typename returnType, typename ...argumentType>
class Delegate
{
public:
typedef returnType (hostClassType::*ClassFunctionType)(argumentType...);
Delegate(hostClassType* obj, ClassFunctionType func)
{
m_HostObject = obj;
m_ClassFunction = func;
}
private:
hostClassType* m_HostObject;
ClassFunctionType m_ClassFunction;
}
Visual Studio 2019 compile it with error:
Error C2825: 'hostClassType': must be a class or namespace when followed by '::'
Tried with <typename hostClassType> and <class hostClassType> in the template. none of them works. Does anyone know what is the problem with the code?
Thank you very much
I was trying to port an open sourced project from linux to window, there are some code that compiles perfectly in linux using either g++ or clang++, but I cannot compile it under MSVC 2015, could anyone tell me how to fix it or how to get around it? I appreciate very much for your help!!!
Here is the code (I have simplified it so you can focus on the key stuff)
template <typename T, class IsMatch = void>
class vc_hashkey
{
public:
static constexpr bool holds_value() { return false; }
};
template <typename T>
class vc_hashkey<T, typename std::enable_if<std::is_integral<T>::value>::type>
{
public:
static constexpr bool holds_value() { return true; }
};
template <typename T, class IsMatch = void>
class vc_hashkey_and_value
{
};
template <typename T>
class vc_hashkey_and_value<T, typename std::enable_if<vc_hashkey<T>::holds_value()>::type>
{
};
That's it, I did not even used these code pieces in my main function. When I tried to compile, the msvc 2015 update RC1 compiler gives me compile errors on the partial specialization of the class vc_hashkey_and_value, saying:
C2039 'type': is not a member of 'std::enable_if<'false, void>'
C2146 syntax error: missing '>' before identifier 'type'
C2064 term does not evaluate to a function taking 0 arguments
Is this a MSVC compiler error, thanks for helping me!!!
It appears that MSVC 2012 doesn't support using K = ...;-type declarations. For example, with the code:
template <class Map>
inline void foo(Map &m)
{
using K = typename Map::key_type;
using V = typename Map::mapped_type;
// ...
}
The result is a syntax error:
error C2143: syntax error : missing ';' before '='
error C2873: 'K' : symbol cannot be used in a using-declaration
How can I work around this missing feature of MSVC 2012, without upgrading the compiler?
Microsoft's support for C++11 is incomplete, and this is one of the things that's missing in VS2012. But in this case, you should be able to use an old-fashioned typedef; e.g.:
typedef typename Map::key_type K;
The place where this workaround falls apart is when the type is templated:
template<typename T>
using Bar = Foo<T>; // ok if your compiler supports it
template<typename T>
typedef Foo<T> Bar; // doesn't compile
But then you still at least have this option:
template<typename T>
struct Bar
{
typedef Foo<T> type;
};
Sorry, I couldn't frame a question that could capture my problem properly. My problem is this.
I have a templated class like this. I am not able to understand how exactly to define the Get function.
template<class Data>
class Class
{
struct S
{
};
void Do();
S Get();
};
template<class Data>
void Class<Data>::Do()
{
}
template<class Data>
Class<Data>::S Class<Data>::Get()
{
}
I get the following errors
1>error C2143: syntax error : missing ';' before 'Class<Data>::Get'
1>error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>fatal error C1903: unable to recover from previous error(s); stopping compilation
template<class Data>
Class<Data>::S Class<Data>::Get()
needs to be
template<class Data>
typename Class<Data>::S Class<Data>::Get()
because S is a dependent type. Any time you have a type that's nested in a template you need to use the keyword typename. For example, an iterator over a vector<int> has the type typename vector<int>::iterator.
A C++11 style, easier to read and write :
template<class Data>
auto Class<Data>::Get() -> S {
return {};
}
How to specialize a class template for a tuple? I try the following but failed. I am using VC Compiler Nov 2012 CTP which support variadic template arguments.
template<class T>
struct A
{
void f() {}
};
template<class... Args>
struct A<tuple<Args...>>
{
void g() {}
};
I try
A<tuple<int, float>> a;
a.g(); // error error C2039: 'g' : is not a member of
//'A<std::tuple<int,float,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil>>
Thanks to yngum. It might be a VC compiler bug. If so, how to work around?
This is a compiler-bug. As a work-around, simply add the 2-parameter specialization
template<class Arg0, class Arg1>
struct A< std::tuple<Arg0, Arg1> >
{
void g() {}
};
Live Example.
Yes, you'll have to do this for as many parameters as your code is likely to use. Or, you could try VS 2013 RC which is likely to have fixed this bug.
Update: I now see that you asked a separate question about the work-arounds. The same solution was posted there.