我正在使用GCC8.2
,我想定义一个这样的分层元组:
std::tuple<std::array<double,N>,
std::array<double,N/2>,
std::array<double,N/4>,
...,
std::array<double,2> > v ;
然后我有一种算法,可以按照以下规范填充这些数组:
template <int N>
std::array<double,N> get_array()
如何编写通用算法来声明元组并在编译时为任何N
填充它?
答案 0 :(得分:3)
没有递归,您可能会做类似的事情:
template <std::size_t N>
std::array<double, N> get_array() { return {{}}; }
namespace detail
{
constexpr std::size_t log2(std::size_t n)
{
std::size_t res = 0;
while (n != 0) {
n /= 2;
++res;
}
return res;
}
template <std::size_t N, std::size_t ...Is>
auto make_array_tuple_impl(std::index_sequence<Is...>)
{
return make_tuple(get_array<(N >> Is)>()...);
}
}
template <std::size_t N>
auto make_array_tuple()
{
return detail::make_array_tuple_impl<N>(std::make_index_sequence<detail::log2(N) - 1>());
}
答案 1 :(得分:2)
这有点涉及,也许有一个更简单的解决方案。
AppiumDriver<AndroidElement> driver;
[TestInitialize]
public void OpenApp()
{
DesiredCapabilities cap = new DesiredCapabilities();
cap.SetCapability("noReset", "true");
cap.SetCapability("device", "Android");
cap.SetCapability("deviceName", "Galaxy S8");
cap.SetCapability("platformVersion", "8.0.0");
cap.SetCapability("platformName", "Android");
cap.SetCapability("automationName", "UiAutomator2");
cap.SetCapability("appPackage", "com.goldex");
cap.SetCapability("appActivity", "com.goldex.view.activity.MainActivity");
driver = new AndroidDriver<AndroidElement>(new Uri("http://127.0.0.1:4723/wd/hub"), cap);
}
[TestMethod]
public void ViewBulbasaur()
{
// Arrange
driver.FindElementByXPath("//android.widget.TextView[contains(@text, 'Bulbasaur')]").Click();
// Assert
var objText = driver.FindElementByXPath("//android.widget.TextView[contains(@text, 'Bulbasaur #001')]").Text;
Assert.AreEqual("Bulbasaur #001", objText);
}
[TestMethod]
public void ViewIvysaur()
{
//Arrange
driver.FindElementByXPath("//android.widget.TextView[contains(@text, 'Ivysaur')]").Click();
// Assert
var objText = driver.FindElementByXPath("//android.widget.TextView[contains(@text, 'Ivysaur #002')]").Text;
Assert.AreEqual("Ivysaur #002", objText);
}
[TestMethod]
public void ViewVenusaur()
{
//Arrange
driver.FindElementByXPath("//android.widget.TextView[contains(@text, 'Venusaur')]").Click();
// Assert
var objText = driver.FindElementByXPath("//android.widget.TextView[contains(@text, 'Venusaur #003')]").Text;
Assert.AreEqual("Venusaur #003", objText);
}
[TestMethod]
public void ViewMegaVenusaur()
{
//Arrange
driver.FindElementByXPath("//android.widget.TextView[contains(@text, 'Mega Venusaur')]").Click();
// Assert
var objText = driver.FindElementByXPath("//android.widget.TextView[contains(@text, 'Mega Venusaur #003')]").Text;
Assert.AreEqual("Mega Venusaur #003", objText);
}
[TestMethod]
public void ViewCharmander()
{
//Arrange
driver.FindElementByXPath("//android.widget.TextView[contains(@text, 'Charmander')]").Click();
// Assert
var objText = driver.FindElementByXPath("//android.widget.TextView[contains(@text, 'Charmander #004')]").Text;
Assert.AreEqual("Charmander #004", objText);
}
[TestCleanup]
public void CloseApp()
{
driver.CloseApp();
}
答案 2 :(得分:1)
您确定
中的序列吗std::tuple<std::array<double,N>,
std::array<double,N/2>,
std::array<double,N/4>,
...,
std::array<double,2> > v ;
以2
结尾吗?
假设您想以2
或1
结尾,我想您可以使用以下自定义类型特征获取所需的索引序列
template <std::size_t N, std::size_t ... Is>
struct divSequence : public divSequence<(N>>1u), Is..., (N>>1u)>
{ };
template <std::size_t ... Is>
struct divSequence<2u, Is...> : public std::index_sequence<Is...>
{ };
template <std::size_t ... Is>
struct divSequence<1u, Is...> : public std::index_sequence<Is...>
{ };
因此,您仅需要以下make函数(带有帮助程序)
template <std::size_t ... Is>
std::tuple<std::array<double, Is>...>
getDivTupleHelper (std::index_sequence<Is...> const &)
{ return { get_array<Is>()... }; }
template <std::size_t N>
auto getDivTuple ()
{ return getDivTupleHelper(divSequence<N>{}); }
以下是完整的C ++ 14示例
#include <array>
#include <tuple>
#include <utility>
template <std::size_t N>
std::array<double,N> get_array ()
{ return {{ }}; }
template <std::size_t N, std::size_t ... Is>
struct divSequence : public divSequence<(N>>1u), Is..., (N>>1u)>
{ };
template <std::size_t ... Is>
struct divSequence<2u, Is...> : public std::index_sequence<Is...>
{ };
template <std::size_t ... Is>
struct divSequence<1u, Is...> : public std::index_sequence<Is...>
{ };
template <std::size_t ... Is>
std::tuple<std::array<double, Is>...>
getDivTupleHelper (std::index_sequence<Is...> const &)
{ return { get_array<Is>()... }; }
template <std::size_t N>
auto getDivTuple ()
{ return getDivTupleHelper(divSequence<N>{}); }
int main ()
{
using t0 = decltype( getDivTuple<15u>() );
using t1 = std::tuple<std::array<double, 7u>,
std::array<double, 3u>,
std::array<double, 1u>>;
using t2 = decltype( getDivTuple<16u>() );
using t3 = std::tuple<std::array<double, 8u>,
std::array<double, 4u>,
std::array<double, 2u>>;
static_assert( std::is_same<t0, t1>::value, "!");
static_assert( std::is_same<t2, t3>::value, "!");
}
如果您需要C ++ 11解决方案...那么...代替std::index_sequence
,可以使用自定义平凡替代品
template <std::size_t ...>
struct myIndexSequence
{ }
,您需要重写getDivTuple()
以使用decltype()
显式地返回类型;像
template <std::size_t N>
decltype(getDivTupleHelper(divSequence<N>{})) getDivTuple ()
{ return getDivTupleHelper(divSequence<N>{}); }