我如何 "generate" 从可变参数模板参数中为函数模板特殊化?
How can I "generate" template spezialations for a function from a variadic template argument?
我想我会先展示例子然后解释它:
#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, 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
,其中包含如何在 getArray
中构造 arr
的信息。 args 列表被传递给 Foo
。现在我希望为 Arguments
中的每个 arg
生成 getArray
的模板特化。如果没有为特定的 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, typename... Rest>
struct contains<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, 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, 10>, arg<float, 10>, arg<float, 1>> myFoo2;
std::cout << myFoo2.getArray<arg<int, 10>>()[5];
Foo<arg<int, 10>, arg<float, 10>, arg<double, 1>> myFoo3;
std::cout << myFoo3.getArray<arg<int, 10>>()[5];
}
还想指出,如代码所示,myFoo
和 myFoo2
returns 是相同的数组,因为它们是完全相同的类型。
另一方面,myFoo3
是一个单独的类型,这意味着 getArray
成员函数是一个单独的函数,并且有自己的相同类型数组的副本。
我想我会先展示例子然后解释它:
#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, 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
,其中包含如何在 getArray
中构造 arr
的信息。 args 列表被传递给 Foo
。现在我希望为 Arguments
中的每个 arg
生成 getArray
的模板特化。如果没有为特定的 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, typename... Rest>
struct contains<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, 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, 10>, arg<float, 10>, arg<float, 1>> myFoo2;
std::cout << myFoo2.getArray<arg<int, 10>>()[5];
Foo<arg<int, 10>, arg<float, 10>, arg<double, 1>> myFoo3;
std::cout << myFoo3.getArray<arg<int, 10>>()[5];
}
还想指出,如代码所示,myFoo
和 myFoo2
returns 是相同的数组,因为它们是完全相同的类型。
myFoo3
是一个单独的类型,这意味着 getArray
成员函数是一个单独的函数,并且有自己的相同类型数组的副本。