问题描述
我想我会先展示这个例子然后再解释它:
#include <array>
template<typename T_,size_t size_>
struct arg
{
using T = T_;
static constexpr size_t size = size_;
};
template<typename... Arugments>
struct Foo
{
template<typename Argument>
std::array<typename Argument::T,Argument::size>& getArray() // specializations of all args in Arguments should be generated
{
static std::array<typename Argument::T,Argument::size> arr;
return arr;
}
};
int main()
{
Foo<arg<int,10>,arg<float,1>> myFoo;
myFoo.getArray<arg<int,10>>();
myFoo.getArray<arg<float,10>>(); // should return a different array than the line above
myFoo.getArray<arg<bool,1>>(); // should NOT work because arg<bool,10> is was not passed to Foo
}
如果得到一个结构体 arg
,其中包含如何在 arr
中构造 getArray
的信息。参数列表传递给 Foo
。现在我希望为 getArray
中的每个 arg
生成 Arguments
的模板特化。如果没有为特定的 arg
生成专门化,我希望发生某种错误。
我怎样才能做到这一点?
解决方法
您可以使用 static_assert
来确保 Argument
是带有辅助结构的 Arguments
的一部分。
#include <array>
#include <iostream>
template <typename... T>
struct contains;
template <typename T>
struct contains<T> : std::false_type {};
template <typename T,typename U,typename... Rest>
struct contains<T,U,Rest...> : contains<T,Rest...> {};
template <typename T,T,Rest...> : std::true_type {};
template<typename T_,std::size_t size_>
struct arg
{
using T = T_;
static constexpr std::size_t size = size_;
};
template<typename... Arguments>
struct Foo
{
template<typename Argument>
std::array<typename Argument::T,Argument::size>& getArray() // specializations of all args in Arguments should be generated
{
static_assert(contains<Argument,Arguments...>(),"Invalid type");
static std::array<typename Argument::T,Argument::size> arr;
return arr;
}
};
int main()
{
Foo<arg<int,10>,arg<float,1>> myFoo;
myFoo.getArray<arg<int,10>>()[5] = 7;
myFoo.getArray<arg<float,10>>(); // should return a different array than the line above
//myFoo.getArray<arg<bool,1>>(); // should NOT work because arg<bool,10> is was not passed to Foo
Foo<arg<int,1>> myFoo2;
std::cout << myFoo2.getArray<arg<int,10>>()[5];
Foo<arg<int,arg<double,1>> myFoo3;
std::cout << myFoo3.getArray<arg<int,10>>()[5];
}
还想指出,如代码所示,myFoo
和 myFoo2
返回相同的数组,因为它们是完全相同的类型。
myFoo3
另一方面是一个单独的类型,这意味着 getArray
成员函数是一个单独的函数并且拥有它自己的相同类型数组的副本。