2015-11-01 65 views
2
template <typename IN,typename OUT,bool isVector> 
OUT foo(IN x){ 
    if (isVector){ 
     return x[0];  
    } else { 
     return x; 
    } 
} 

在询问this question之后,我错误地认为上述代码可以编译为例如。如何修复此模板:

foo<double,double,false>; 

以及

foo<std::vector<double>,double,true>; 

然而,即使如果支行从未得到执行的一个,检查的正确性,因此上面没有编译。我该如何解决它?

上面的代码是一个简化,但我不知道如何解决它,因为函数模板不能有偏特...

回答

4

可以“提取”你要专注于模板参数,使他们一些结构的模板参数,并写有剩余的模板参数静态成员函数的函数:

template<bool IsVector = true> 
struct Bar { 
    template<typename In> 
    static auto foo(In input) { 
     return input[0]; 
    } 
}; 
template<> 
struct Bar<false> { 
    template<typename In> 
    static auto foo(In input) { 
     return input; 
    } 
}; 

Live example.

显然,这导致在调用位置变化,这哟ü可以“捕获”使用被调用相应功能的免费功能:

template<typename In, bool IsVector> 
auto real_foo(In input) { 
    return Bar<IsVector>::foo(input); 
} 

结构(Bar),然后通常把一个“帮手”命名空间内。


另一种可能性是使用标签和重载决议:

template<typename In> 
auto foo(In input, std::true_type) { 
    return input[0]; 
} 
template<typename In> 
auto foo(In input, std::false_type) { 
    return input; 
} 
template<bool IsVector, typename In> 
auto foo(In input) { 
    using tag = typename conditional<IsVector, true_type, false_type>::type; 
    return foo(input, tag{}); 
} 

Live example.

这使用std::conditionalstd::true_typestd::false_type不同类型允许重载决议找到合适的foo功能。

+0

看起来不错,我会尝试 – user463035818

+0

我更喜欢第一个解决方案,第二个看起来像C++ 11,我不能使用不幸的。然而,从模板类“A”调用函数时,我无法运行它,并且我传递的模板参数(代码中的“In”)是“A”的模板参数。任何想法,为什么这可能是?我将尝试将其制作成MCVE ... – user463035818

+0

不编译的MCVE:http://ideone.com/NQwfyA – user463035818