标签: template-templates

模板模板,可变参数模板和演绎指南:编译器错误?

考虑以下高度模板化的代码:

// Preamble
#include <list>
#include <deque>
#include <vector>
#include <iostream>
#include <type_traits>

// Rebind template template type traits
template <class> struct rebind_template_template;
template <template <class...> class Template, class... Types>
struct rebind_template_template<Template<Types...>> {
    template <class... Args>
    using type = Template<Args...>;
};

// Rebind template parameters type traits
template <class> struct rebind_template_parameters;
template <template <class...> class Template, class... Types>
struct rebind_template_parameters<Template<Types...>> {
    template <template <class...> class Arg>
    using type = Arg<Types...>;
};

// Template pack
template <template <class...> class... Templates>
class …
Run Code Online (Sandbox Code Playgroud)

c++ template-templates compiler-bug template-argument-deduction c++17

5
推荐指数
0
解决办法
95
查看次数

使用std :: tuple作为模板参数列表而不是类型列表

我正试图调用这样的模板化函数:

typedef std::tuple<int, double, bool> InstrumentTuple;

Cache cache;
InstrumentTuple tuple = cache.get<InstrumentTuple>();
Run Code Online (Sandbox Code Playgroud)

我知道我可以"简单地"传递元组的类型.这就是我所知道的但是它非常麻烦,因为我对这个函数进行了很多调用,因为元组很长:

InstrumentTuple tuple = c.get<int, double, bool>(); // syntax I'd like to avoid
Run Code Online (Sandbox Code Playgroud)

所以我尝试了get方法的多个实现,但没有成功:

通过模板参数启用

#include <tuple>

class Cache
{
private:
    template<int I, typename T, typename = typename std::enable_if<I == std::tuple_size<T>::value>::type>
    std::tuple<> get() // line 6
    {
        return std::tuple<>();
    }

    template<int I, typename T, typename = typename std::enable_if<I != std::tuple_size<T>::value>::type>
    std::tuple<typename std::tuple_element<I,T>::type, decltype(get<I+1, T>())> get() // line 12
    {
        std::tuple<typename std::tuple_element<I,T>::type> value;
        return std::tuple_cat(value, get<I+1, T>());
    }

public: …
Run Code Online (Sandbox Code Playgroud)

c++ tuples template-templates enable-if variadic-templates

4
推荐指数
1
解决办法
4079
查看次数

是否可以完善转发模板模板参数

我知道如何完善一个参数.但是,我从不同的来源(例如,有效的现代C++第24项 - 斯科特迈耶斯)中读到,当你拥有确切的模板名称时,人们只能完美地前进,例如:

template<typename T>
void foo(T&& param) { bar(std::forward<T>(param)); }
Run Code Online (Sandbox Code Playgroud)

我正在寻找的是,如果有一种方法可以完美地转发模板模板参数,例如:

template<template<int, class TypeT> class Vector, int Size, typename TypeT>
void foo(Vector<Size, TypeT>&& param) { bar(std::forward<Vector<Size, TypeT>>(param)); }
Run Code Online (Sandbox Code Playgroud)

当我编译上面的代码时,我收到一条错误消息:"你不能将左值绑定到右值引用"(VC12),这告诉我编译器不会将&&识别为"通用引用",而是将其作为右值引用.这个完美的前锋对我来说很有用,因为我可以利用推导出的TypeT和Size.

问题:是否可以完善转发模板模板参数?如果是这样,我的语法在哪里不正确?

谢谢!

c++ template-templates perfect-forwarding

4
推荐指数
1
解决办法
689
查看次数

如何检查模板模板类的接口

我试图根据模板模板参数是否具有在其中type定义的类型(例如,std::remove_reference具有type成员类型别名)来使用SFINAE重载模板类,但我无法找到一个好的方法来执行此操作.

例如,我想做

template <template <typename...> class Trait>
using EnableIfHasTypeMember = std::void_t<Trait::type>;

template <template <typename...> class Trait, typename OtherStuff,
          EnableIfHasTypeMember<Trait>* = nullptr>
class Something { ... }
Run Code Online (Sandbox Code Playgroud)

但这给了我一个编译器错误.有什么办法可以检查模板模板参数的界面吗?

c++ templates template-templates c++11 c++14

4
推荐指数
1
解决办法
167
查看次数

template 模板类,如果存在则调用函数

我有一个带有模板模板参数的简单函数。它的目的是采用一个STL容器,将智能ptr转换为普通ptr(这是一个C++03项目,但我也对C++11的答案感兴趣):

template <template <typename _T, typename = std::allocator<_T> > class Container>
static Container<T*> GetRawPtrContainer(const Container<SmartPtr<T> >& input_container)
{
    Container<T*> container;
    for(typename Container<SmartPtr<T> >::const_iterator it = input_container.begin();
        it != input_container.end();
        it++)
    {
        container.push_back(it->ptr);
    }
    return container;
}
Run Code Online (Sandbox Code Playgroud)

这是类的静态成员函数SmartPtr<T>

你在这里看到的,这一切所做的就是将push_back所有元素从input_container另一个元素转移到另一个元素并返回。

您可能已经注意到,如果输入是std::vector,则插入会出现性能问题,而这对于和O(1)来说没问题。所以我想做的是在循环之前调用它(如果可能的话)(在编译时决定)std::liststd::deque

container.reserve(input_container.size());
Run Code Online (Sandbox Code Playgroud)

我怎样才能做到这一点?

c++ templates stl template-templates c++11

4
推荐指数
1
解决办法
2130
查看次数

SFINAE优雅地检查"模板模板类"(在模板参数中)

如何在模板参数中检查模板模板类的类型?

B<T>并且C<T>是模板类.
我想创建一个D<class BC>可以D<B>或者的类D<C>.
只有D<B>拥有D::f().

这是我的解决方法(演示).有用.

#include <iostream>
using namespace std;
class Dummy{};
template<class T>class B{};
template<class T>class C{};
template<template<class T> class BC>class D{
    //f() is instantiated only if "BC" == "B"
    public: template<class BCLocal=BC<Dummy>> static
    typename std::enable_if<std::is_same<BCLocal,B<Dummy>>::value,void>::type f(){  
    }
    //^ #1
};
int main() {
    D<B>::f();
    //D<C>::f();   //compile error as expected, which is good
    return 0;
} 
Run Code Online (Sandbox Code Playgroud)

这条线#1很长很难看(Dummy用来破解).
在实际程序中,它也容易出错,特别是当 …

c++ sfinae template-templates c++14

4
推荐指数
1
解决办法
217
查看次数

用于接收通用映射作为参数的模板函数

可能存在许多情况,其中我们想要在a std::mapstd::unordered_map完全相同的情况下执行某些操作,而与地图的类型无关.让我们考虑以下示例:

#include <map>
#include <unordered_map>
#include <iostream>

template< template <typename,typename> class Container >
void printMap(Container<int, long> inputMap, bool additionalParam = false)
{
    for (const pair<int,long> p : inputMap)
        cout<<p.first <<","<< p.second <<std::endl;
}

int main()
{
int a = 1;
long b = 2;
map<int,long> map1;
map1.emplace(a,b);
unordered_map<int,long> map2;
map2.emplace(a,b);
printMap(map1);
printMap(map2);

return EXIT_SUCCESS;
}
Run Code Online (Sandbox Code Playgroud)

如果我尝试编译上面的例子,我有这个:

error: no matching function for call to ‘printMap(std::map<int, long int>&)’
Run Code Online (Sandbox Code Playgroud)

我在这篇文章中读到了模板模板的使用.这样做的正确方法是什么?

c++ templates stdmap template-templates c++11

4
推荐指数
2
解决办法
2198
查看次数

未定义的对专用模板成员的引用

我有一个由模板模板类参数化的类,它具有静态成员函数:

template <template <typename> class F>
struct A {
  static int foo();
};
Run Code Online (Sandbox Code Playgroud)

此类没有默认定义foo,必须专门针对不同类型.

我还有一个带有嵌套模板类的模板模板类参数化的另一个类:

template <template <typename> class F>
struct B {
  template <typename T>
  struct C {};
};
Run Code Online (Sandbox Code Playgroud)

我想C专门A用于任何模板模板类F,专门A不已:

template <template <typename> class F>
struct A<B<F>::template C> {
  static int foo();
};

template <template <typename> class F>
int A<B<F>::template C>::foo() {
  return A<F>::foo() / 2;
}
Run Code Online (Sandbox Code Playgroud)

所以,如果我有一个专门的课程A:

template <typename T>
struct E {};

template <>
int …
Run Code Online (Sandbox Code Playgroud)

c++ templates partial-specialization template-templates

4
推荐指数
1
解决办法
123
查看次数

将模板的模板成员类型作为模板模板参数传递

一个类WithTTMember有一个名为 的模板成员类型TT

struct WithTTMember {
    template<typename> using TT = void;
};
Run Code Online (Sandbox Code Playgroud)

另一个类ExpectTT采用模板模板参数:

template< template<typename> typename TT >
struct ExpectTT {};
Run Code Online (Sandbox Code Playgroud)

ExpectTT<WithTTMember::TT> 可以成功实例化。

第三个类ExpectTWithTT需要一个模板成员类型名为 的模板参数TT,并ExpectTT使用它进行实例化:

template<typename T>
struct ExpectTWithTT {
    using X = ExpectTT<typename T::TT>;  // this doesn't compile
};
Run Code Online (Sandbox Code Playgroud)

我希望ExpectTWithTT<WithTTMember>::XExpectTT<WithTTMember::TT>. 但是上面的代码无法编译。

我尝试在编译器消息和我的直觉之后使用templatetypename关键字的组合注入错误的行,但我无法让它工作。

我怎样才能表达我想要的?

任何 C++ 版本都可以。

c++ templates template-templates

4
推荐指数
1
解决办法
33
查看次数

Visual C++ 无法推导模板模板参数

以下 C++17 代码片段在 GCC 和 CLang 中进行编译,但在 Visual C++ 中会出现以下错误:

<source>(14): error C2672: 'f': no matching overloaded function found
<source>(14): error C2784: 'std::ostream &f(std::ostream &,const container<int> &)': could not deduce template argument for 'const container<int> &' from 'const std::vector<int,std::allocator<int>>'
<source>(5): note: see declaration of 'f'
Run Code Online (Sandbox Code Playgroud)

https://godbolt.org/z/aY769qsfK

#include <vector>

template< template <typename...> typename container >
void f (const container< int > &)
{ }

int main()
{
    std::vector<int> seq = {1, 2, 3};
    f<std::vector>(seq); // OK
    f(seq);              // ERROR
}
Run Code Online (Sandbox Code Playgroud)

请注意,此代码类似于 …

c++ templates template-templates template-argument-deduction c++17

4
推荐指数
1
解决办法
1806
查看次数