我有一段非常复杂的代码,我将其简化为此复制器:
#include <type_traits>
#include <tuple>
template<typename ...As>
struct outer {
template<typename ...Bs>
struct inner {
template<bool dummy, typename E = void>
struct problem;
using TA = std::tuple<As...>;
using TB = std::tuple<Bs...>;
template<bool dummy>
struct problem<dummy, typename std::enable_if<std::tuple_size<TA>::value < std::tuple_size<TB>::value>::type>
{
static constexpr auto val() { return 1; } // actually a complex function
};
template<bool dummy>
struct problem<dummy, typename std::enable_if<std::tuple_size<TA>::value >= std::tuple_size<TB>::value>::type>
{
static constexpr auto val() { return 0; }
};
};
};
int main() {
return outer<int, float>::inner<double>::problem<false>::val();
}
它不能编译(用gcc或clang),说:
<source>:13:82: error: failed requirement 'std::tuple_size<std::tuple<int, float> >::value < std::tuple_size<std::tuple<double> >::value'; 'enable_if' cannot be used to disable this declaration
struct problem<dummy, typename std::enable_if<std::tuple_size<TA>::value <std::tuple_size<TB>::value>::type>
~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~
<source>:27:31: note: in instantiation of template class 'outer<int, float>::inner<double>' requested here
return outer<int, float>::inner<double>::problem<false>::val();
我尝试了一些变体,但没有任何效果。
我阅读了一些已经发布的问答,例如: this one 或this one 但他们似乎没有回答我的问题。
PS:我可以使用C ++ 17,但是必须与任何编译器一起使用。
答案 0 :(得分:2)
建议:尝试以下操作
struct inner {
using TA = std::tuple<As...>;
using TB = std::tuple<Bs...>;
template<bool dummy, typename UA = TA, typename E = void>
struct problem;
template<bool dummy, typename UA>
struct problem<dummy, UA,
std::enable_if_t<(std::tuple_size_v<UA> < std::tuple_size_v<TB>)>>
{ static constexpr auto val() { return 1; } };
template<bool dummy, typename UA>
struct problem<dummy, UA,
std::enable_if_t<(std::tuple_size_v<UA> >= std::tuple_size_v<TB>)>>
{ static constexpr auto val() { return 0; } };
};
我的意思是……算是SFINAE可以对要启用/禁用的struct / class(或函数或方法)的模板参数进行测试。
原始代码中的问题是SFINAE测试仅考虑TA
和TB
,它们是在inner
结构中定义的类型,其中包含problem
。因此,测试仅取决于外部模板参数(As...
和Bs...
),而不取决于problem
的模板参数。
添加默认值为problem
的模板参数
// ..................VVVVVVVVVVVVVVVVV
template<bool dummy, typename UA = TA, typename E = void>
struct problem;
不会改变problem
本身的实际用途,而是会转换std::enable_if
中的测试
template<bool dummy, typename UA>
struct problem<dummy, UA, // ..........VV UA, not TA
std::enable_if_t<(std::tuple_size_v<UA> < std::tuple_size_v<TB>)>>
{ static constexpr auto val() { return 1; } };
在涉及problem
模板参数本身的测试中。
答案 1 :(得分:1)
如注释中所建议,使用if constexpr
(C ++ 17的一部分)使代码更简单:
template<typename ...As>
struct outer {
template<typename ...Bs>
struct inner {
using TA = std::tuple<As...>;
using TB = std::tuple<Bs...>;
struct problem
{
static constexpr auto val()
{
if constexpr (std::tuple_size<TA>::value < std::tuple_size<TB>::value)
return 1; // Complex function goes here
else
return 0; // Other complex function (?) goes here
}
};
};
};
答案 2 :(得分:1)
正如@unimportant所评论:if-constexpr自C ++ 17起。使您摆脱<div class="row">
<div class="card">
<img src="https://animatedanatomy.com/images/16-9-dummy-image6.jpg" alt="Snow" style="width:100%">
<img class="imageoverlay" src="http://barricadeprinters.com/wp-content/uploads/2018/10/16-9placeholder.png" />
</div>
<div class="card">
<img src="https://animatedanatomy.com/images/16-9-dummy-image6.jpg" alt="Forest" style="width:100%">
<img class="imageoverlay" src="http://barricadeprinters.com/wp-content/uploads/2018/10/16-9placeholder.png" />
</div>
<div class="card">
<img src="https://animatedanatomy.com/images/16-9-dummy-image6.jpg" alt="Forest" style="width:100%">
<img class="imageoverlay" src="http://barricadeprinters.com/wp-content/uploads/2018/10/16-9placeholder.png" />
</div>
</div>
<div class="row">
<div class="card">
<img src="https://animatedanatomy.com/images/16-9-dummy-image6.jpg" alt="Snow" style="width:100%">
<img class="imageoverlay" src="http://barricadeprinters.com/wp-content/uploads/2018/10/16-9placeholder.png" />
</div>
<div class="card">
<img src="https://animatedanatomy.com/images/16-9-dummy-image6.jpg" alt="Forest" style="width:100%">
<img class="imageoverlay" src="http://barricadeprinters.com/wp-content/uploads/2018/10/16-9placeholder.png" />
</div>
<div class="card">
<img src="https://animatedanatomy.com/images/16-9-dummy-image6.jpg" alt="Forest" style="width:100%">
<img class="imageoverlay" src="http://barricadeprinters.com/wp-content/uploads/2018/10/16-9placeholder.png" />
</div>
</div>
和更多行:
dummy
程序“ [4544] main.exe”已退出,代码为0(0x0)。