考虑以下高度模板化的代码:
// 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
我正试图调用这样的模板化函数:
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++第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.
问题:是否可以完善转发模板模板参数?如果是这样,我的语法在哪里不正确?
谢谢!
我试图根据模板模板参数是否具有在其中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)
但这给了我一个编译器错误.有什么办法可以检查模板模板参数的界面吗?
我有一个带有模板模板参数的简单函数。它的目的是采用一个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)
我怎样才能做到这一点?
如何在模板参数中检查模板模板类的类型?
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用来破解).
在实际程序中,它也容易出错,特别是当 …
可能存在许多情况,其中我们想要在a std::map或std::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)
我在这篇文章中读到了模板模板的使用.这样做的正确方法是什么?
我有一个由模板模板类参数化的类,它具有静态成员函数:
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) 一个类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>::X与ExpectTT<WithTTMember::TT>. 但是上面的代码无法编译。
我尝试在编译器消息和我的直觉之后使用template和typename关键字的组合注入错误的行,但我无法让它工作。
我怎样才能表达我想要的?
任何 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