这绝对是一个微不足道的问题,但我无法弄清楚如何做到这一点。
我有一个模板功能,比如select TOTAL_DELIVERY.CUSTOMER_NAME,
TOTAL_DELIVERY.CONTAINER_TYPE,
coalesce(TOTAL_DELIVERY.TOTAL_QUANTITY, 0) as TOTAL_DELIVERY,
coalesce(TOTAL_PULLOUT.TOTAL_QUANTITY, 0) as TOTAL_PULLOUT,
coalesce((TOTAL_DELIVERY.TOTAL_QUANTITY - TOTAL_PULLOUT.TOTAL_QUANTITY), 0) as CUSTOMER_BALANCE
from TOTAL_DELIVERY
left join TOTAL_PULLOUT
on TOTAL_DELIVERY.CUSTOMER_NAME = TOTAL_PULLOUT.CUSTOMER_NAME
and TOTAL_DELIVERY.CONTAINER_TYPE = TOTAL_PULLOUT.CONTAINER_TYPE
Deliveries Table (View)
================
----------------------------------------------
CUSTOMER_NAME| CONTAINER_TYPE | TOTAL_QUANTITY
-------------+----------------+---------------
Bryan | Slim | 5
-------------+----------------+---------------
Bryan | Jug | 5
-------------+----------------+---------------
Returns Table (View)
=============
CUSTOMER_NAME| CONTAINER_TYPE| TOTAL_QUANTITY
-------------+---------------+---------------
Bryan | Slim | 5
-------------+---------------+---------------
Expected output
===============
Customer | Container | Total_Delivery | Total_Return | Customer_Balance |
---------+-----------+----------------+--------------+------------------
Bryan | Slim | 5 | 5 | 0 |
---------+-----------+----------------+--------------+------------------
Bryan | Jug | 5 | 0 | 5 |
---------+-----------+----------------+---------------------------------
My INCORRECT Result output (incorrect result at the bottom right cell)
=========
Customer | Container | Total_Delivery | Total_Return | Customer_Balance |
---------+-----------+----------------+--------------+------------------
Bryan | Slim | 5 | 5 | 0 |
---------+-----------+----------------+--------------+------------------
Bryan | Jug | 5 | 0 | 0 |
---------+-----------+----------------+---------------------------------
。现在,template <unsigned int N> void my_function()
有两个不同的实现,如果my_function
大于100,则应使用第一个,如果N
小于此值,则应使用另一个。
我试着像这样使用SFINAE:
N
但那是两次声明相同的功能。然后我尝试做类似
的事情template <unsigned int N, typename = enable_if <N >= 100> :: type> my_function()
{
// First implementation
}
template <unsigned int N, typename = enable_if <N < 100> :: type> my_function()
{
// Second implementation
}
然后使用两个不同的布尔值实现这两个函数。没有成功,因为它是部分专业化。
然后我尝试将template <unsigned int N, bool = (N >= 100)> my_function();
包装为struct参数,并在函数调用中包含bool,但它在专门化类之前专门化了一个成员函数,这是无法完成的。
有合理的方法吗?
答案 0 :(得分:12)
请改为尝试:
#include <type_traits>
#include <iostream>
template <unsigned int N, typename std::enable_if <N >= 100> :: type* = nullptr>
void my_function()
{
std::cout << "N >= 100" << std::endl;
}
template <unsigned int N, typename std::enable_if <N < 100> :: type* = nullptr>
void my_function()
{
std::cout << "N < 100" << std::endl;
}
int main()
{
my_function<42>();
my_function<100>();
}
Template default parameters do not participate in the overload(因此SFINAE不适用)。另一方面,在上面的代码片段中,依赖模板非类型参数位于赋值的左侧,因此SFINAE启动。
答案 1 :(得分:5)
如果由于某种原因你不喜欢enable_if,你总是可以去标签发送:
String myShapes="circle,square,circle,rectangle" // This is from a property file
for ( shapeType : myShapes.split("," ) {
ShapeFactory shapeFactory = new ShapeFactory();
Shape shape1 = shapeFactory.getShape(shapeType );
shape1.doSomething();
}
在这种情况下,我们可以将标签限制为像true_type和false_type这样的简单事物,但通常这可能是另一种方法。
答案 2 :(得分:2)
您可以在退货类型上使用SFINAE:
template <unsigned int N>
enable_if_t<(N >= 100)> my_function()
{
// First implementation
}
template <unsigned int N>
enable_if_t<(N < 100)> my_function()
{
// Second implementation
}
目前,您template <unsigned int N, typename T>
只有T
具有不同的默认类型。
对于部分专业化,您可以转发到结构:
template <unsigned int N, bool = (N >= 100)>
struct my_function_impl;
template <unsigned int N>
struct my_function_impl<N, true>
{
void operator () const { /* First implementation */}
};
template <unsigned int N>
struct my_function_impl<N, false>
{
void operator () const { /* Second implementation */}
};
template <unsigned int N>
void my_function() { my_function_impl<N>{}(); }