Template template for std::vector fails to build on icc16 - c++11

I have a class that has a container in it. This container must be a template and must accept std::vector. The code needs to be C++11 standard. I have simplified for this question, but it is equivalent to:
#include <vector>
template <template <typename, typename...> class Container>
class Test {
Container<double> c;
};
class TestImplementation : public Test<std::vector> {};
Recently I have found this fails to build for icpc16 as shown by CompilerExplorer https://godbolt.org/g/AGgojV with the error message:
too few arguments for template template parameter "Container"
Container<double> c;
It compiles for gcc, clang and icpc17. Is this a bug in icpc16 or is my code incorrect?

Related

Dynamic pointer cast compile error when I compile with C++11

I'm developping an app with OpenFrameworks with C++ language.
In my program there is a line that makes a dynamic cast pointer
Ref_<ImageUniform> p = o.cast<ImageUniform>();
Here is the class that implementing the cast() function implementation
template <typename T>
struct Ref_ : public ofPtr<T>
{
Ref_() {}
Ref_(T *t) : ofPtr<T>(t) {}
Ref_(const Ref_<T>& o) : ofPtr<T>(o) {}
Ref_(const ofPtr<T>& o) : ofPtr<T>(o) {}
template <typename TT>
Ref_<TT> cast() const { return dynamic_pointer_cast<TT>(*this); }
};
When I compile without the -std=c++11 it works.
But when I put the -std=c++11 it prints me a compile error and refers me to an internal file "ofTypes.h" of the library of OpenFrameworks at this line 191:
#else
template<typename Tp1>
ofPtr(const ofPtr<Tp1>& __r, std::__dynamic_cast_tag)
: std::shared_ptr<T>(__r, std::__dynamic_cast_tag()) { }
#endif
And also here is the compile error
......\libs\openFrameworks\types\ofTypes.h|193|error: no matching function >for call to 'std::shared_ptr::shared_ptr(const >ofPtr&, std::tr1::__dynamic_cast_tag)'|
#else
template
ofPtr(const ofPtr& __r, std::__dynamic_cast_tag)
: std::shared_ptr(__r, std::__dynamic_cast_tag()) { }
#endif
Either you should update your version of OpenFrameworks (which supports C++11), or you should not compile current code with C++11.
Now you have problem with below code
template<typename Tp1>
ofPtr(const ofPtr<Tp1>& __r, std::__dynamic_cast_tag)
: std::shared_ptr<T>(__r, std::__dynamic_cast_tag()) { }
when you compile this code without C++11, implementation of shared_ptr is taken from tr1/memory header. The code can be compiled because there is version of shared_ptr ctor which takes as second parameter __dynamic_cast_tag. When you try to compile the code with C++11, you will get error because shared_ptr implementation is taken from memory header (where there is no ctor of shared_ptr which takes __dynamic_cast_tag as second parameter).

How to elegantly restrict a template argument to be a `<Certain_Class<AnyT>>`?

How to restrict a template argument of Wrapper to be a Wrapper<Any,MyArray<AnyT>> elegantly?
Don't break content assist (Visual Studio).
High readability. Not use a hacky approach.
For some reasons, most solution love to hack.
Make it obvious at the very first line by using C++ syntax rule. (not just green comment)
As far as I know, there are many solutions, but every solution doesn't meet the criteria.
Workaround 1 (template specialization, fail 1)
template<class T> class MyArray{};
template<class T,class T2> class Wrapper;
template<class T,class T2> class Wrapper<T,MyArray<T2>>{
using Test=int;
};
class B{};
class C{};
int main() {
Wrapper<C,MyArray<B>> wrapper;
return 0;
}
This code is modified from https://stackoverflow.com/a/43518221 (#max66).
Context clue / syntax highlighting of IDE will be confused.
In my case, it marks some correct types as error e.g. :-
class ShowError : public Wrapper<B,MyArray<C>>{
Test n=0; //<-- unknown "Test" (intellisense)
};
Workaround 2 (some hacky field/typedef, fail 2)
template<class T> class MyArray{
public: using MyArrayT=T;
};
template<class T,class T2> class Wrapper{
public: using myT=typename T2::MyArrayT;
//^ assert at compile time
};
This idea come from a comment in https://stackoverflow.com/a/43518295 (#Jarod42)
The class declaration doesn't mention about MyArray, it just uses a hacky (less readable) way (MyArrayT) to enforce that T2 is MyArray.
Workaround 3 (base class, fail 2)
class MyArrayBase{};
template<class T> class MyArray : public MyArrayBase{ };
template<class T,class T2> class Wrapper{
//check something around MyArrayBase *object = new T2();
// or "is_base_of"
};
The code is modified from Restrict C++ Template Parameter to Subclass and C++ templates that accept only certain types.
It has same disadvantage as workaround 2.
It is not obvious for common user.
Workaround 4 (SNIFAE, fail 1)
By adding std::enable_if on the template class declaration (Wrapper), I can get a working hack.
Unfortunately, content assist hate it.
Reference
Here are the other links that I read :-
http://www.informit.com/articles/article.aspx?p=376878 (template template parameter)
restrict a template function, to only allow certain types (not related to template type as a parameter)
You can write a custom type trait is_specialization, as follows:
template<class Type, template<class...> class Template>
struct is_specialization
: std::false_type {};
template<template<class...> class Template, class... TArgs>
struct is_specialization<Template<TArgs...>, Template>
: std::true_type {};
Then you just need to static_assert that is_specialization is true for the given template argument:
template<class T,class T2>
class Wrapper {
static_assert(is_specialization<T2, MyArray>::value, "T2 must be a specialization of MyArray");
};

How to wrap a c++ class with an opencv object with c++/cli

I would like to wrap a complex c++ class which used opencv object with c++/cli for using in c# and vb. I'm using Visual Studio 2015. I'm using the x64 versions of of the OpenCV library and compiling also to x64.
Following is the header.h file of a small test class, just as an example:
#pragma once
#include <vector>
#include "opencv2/opencv.hpp"
using namespace std;
class compC
{
public:
compC(int * pInt, int arrSize);
int sumArray();
private:
vector<int> vec;
cv::Mat img;
};
This is going to be compiled as a win32-application to a .lib file without any problems.
The example wrapper class (wrapper.h) would look like:
#pragma once
#include "../ConsoleApplication1/header.h"
#include "../ConsoleApplication1/body.cpp"
using namespace System;
namespace WrapperLibrary {
public ref class WrapperClass
{
public:
WrapperClass(int * pInt, int arraySize);
int getSum();
private:
compC * pcC;
int sum;
};
}
The second class would be compiled as a dll with /clr (as c++/cli project).
First I got an error that opencv.hpp could not be find and had to add the include directory of opencv in to the wrapper project. But I cannot compile it and get a lot of errors, mainly pointing to linking problems "unresolved external problems ..." in connection with the opencv-mat object.
If I remove the lines
#include "opencv2/opencv.hpp"
and
cv::Mat img;
in the test class (header.h) all will be fine.
What did I made wrong? How can I wrap those c++ class with c++/cli?

Error while trying to use strings while working with windows application forms

When creating a new class while working in a project that is based around windows application forms. I have a problem where string becomes unusable. I get errors the say things like
"a member of a managed class cannot be of a non-managed class type"
"IntelliSense: a function type involving a generic parameter cannot have an ellipsis parameter"
"IntelliSense: linkage specification is incompatible with previous "bsearch_s"(declared at line 426)"
Person.h
#pragma once
#include <string>
using namespace std;
ref class Person
{
public:
Person(void);
string name;
};
Person.cpp
#include "stdafx.h"
#include "Person.h"
#include <string>
using namespace std;
Person::Person(void)
{
name = "Bob";
}
If someone has a solution to this or a work around that isn't creating my own string class I would love to hear it as this has been bothering me for days.
String header in CLI C++ is already included in the System namespace.
String works as a pointer. Using the cap ^ handler
//This works:
#include "stdafx.h"
using namespace System;
void function()
{
String^ simpleStr = "Bob";
}

Using boost::fast_pool_allocator in place of std::allocator

I'm trying to use boost::fast_pool_allocator in place of the standard allocator and it won't work (ironically with another boost library) because fast_pool_allocator has more than one template parameter even though it claims to be compatible with std::allocator and everything except the first has a default value.
I am trying to pass it as a class template that expects a single template parameter. The specific error:
error: type/value mismatch at argument 3 in template parameter list for "template<class Point, template<class, class> class Container, template<class> class Allocator> class boost::geometry::model::multi_point"
error: expected a template of type "template<class> class Allocator", got "template<class T, class UserAllocator, class Mutex, unsigned int NextSize, unsigned int MaxSize> class boost::fast_pool_allocator"
Is there a way to make this actually work?
Use the following template instead of boost::fast_pool_allocator
template <class T>
using fast_pool_allocator_t = boost::fast_pool_allocator<T>;
This will also work if you are not using C++11.
template <class T>
struct fast_pool_allocator_t : boost::fast_pool_allocator<T>
{ };

Resources