转换可变参数函数的参数

时间:2015-08-31 16:45:29

标签: c++ c++11

这可能是一个新手问题,但我认为这可能很有趣。假设我有这个功能:

console.clear();
var arr = [
        ["OPEL", "12365", "TY"],
        ["FORD", "52874", "QW"],
        ["OPEL", "96542", "TY"],
        ["FIAT", "45621", "TY"], 
        ["FIAT", "74125", "QW"],
        ["FORD", "52874", "QW"]
];

function sortAlphabetically(a,b){
  var a_lower = a.toString().toLowerCase(),
      b_lower = b.toString().toLowerCase();

  // sort ascending (a comes first)
  if (a_lower < b_lower)
    return -1;

  // b comes first (move a behind b)
  if (a_lower > b_lower)
    return 1;

  // default: a and b are the same (no sort)
  return 0;
}


function FindDuplicates(){
  arr.sort(sortAlphabetically);

  for (var i = 0; i < arr.length-1; i++){
    if (arr[i+1]+'' == arr[i]+''){
      console.log('Duplicate at: ', 
                  [
                    '[', i, ']',
                    ' and ',
                    '[', i+1, ']',
                    '\n\tvalue: "',arr[i],'"'
                  ].join(''));
    }
  }
}

FindDuplicates();

我想编写第二个函数,在一般情况下调用上面的函数,但在template <typename First, typename... T> int ComputeSomething(const First& f, const T&... t); First类型为T时转换参数,即调用每个参数都有一个float函数:

Convert

我怎样才能做到这一点?

2 个答案:

答案 0 :(得分:3)

选项#1

添加透明的Convert重载,以便绕过非浮点数(也就是说,您可以使用混合类型的参数):

template <typename First, typename... T>
int ComputeSomething(const First& f, const T&... t);

long Convert(float f);

// Transparent converter
template <typename T>
T&& Convert(T&& t) { return std::forward<T>(t); }

template <typename First, typename... Ts>
int MyFun(const First& f, const Ts&... t)
{
    return ComputeSomething(Convert(f), Convert(t)...);
}

DEMO 1

选项#2

(丑陋/容易出错的)。使用SFINAE技术启用/禁用MyFun重载:

#include <type_traits>

template <typename...>
struct type_list {};
template <typename... Ts>
using all_float = std::is_same<type_list<float, Ts...>, type_list<Ts..., float>>;

template <typename First, typename... T>
int ComputeSomething(const First& f, const T&... t) { return 0; }

long Convert(float f) { std::cout << "convert " << f << std::endl; return 0; }

template <typename First, typename... Ts>
auto MyFun(const First& f, const Ts&... t)
    -> typename std::enable_if<!all_float<First, Ts...>::value, int>::type
{
    return ComputeSomething(f, t...);
}

template <typename First, typename... Ts>
auto MyFun(const First& f, const Ts&... t)
    -> typename std::enable_if<all_float<First, Ts...>::value, int>::type
{
    return ComputeSomething(Convert(f), Convert(t)...);
}

DEMO 2

答案 1 :(得分:2)

您可以使用帮助程序来测试所有类型是否为#include <type_traits> template< typename... > struct typelist {}; template< typename T, typename... Ts > using is_all_same = std::is_same< typelist< T, Ts... >, typelist< Ts..., T > >; long Convert(float f); template <typename First, typename... T> typename std::enable_if< !is_all_same< float, First, T... >::value, int >::type MyFun(const First& f, const T&... t) { return ComputeSomething(f, t...); } template <typename First, typename... T> typename std::enable_if< is_all_same< float, First, T... >::value, int >::type MyFun(const First& f, const T&... t) { return ComputeSomething(Convert(f), Convert(t)...); }

std::tuple

帮助程序非常通用,也可以在其他上下文中使用。

编辑:我用typelist替换$(document).ready(function() { $("#mains").one("click", function() { var pmmain = ["aaa", "bbb", "ccc", "ddd", "eee", "fff", "ggg", "hhh", "iii", "jjj", "kkk", "lll", "mmm", "nnn", "ooo", "ppp"]; var a = 0; var b = 0; for (a = 0; a < 4; a++) { //change the value of a to be the limit $("#pm-page-main").append("<div class=\"main-box\"><div class=\"title-box\"><span class=\"reg-wht-bold\">" + pmmain[a] + "</span></div><BR><BR><img src=\"imgs\\" + pmmain[a] + ".png\"></div>"); } }); }); ,尽管在上面的上下文中永远不会实例化元组。我只是为了方便而使用它,但由于有些人认为开销太大,我编辑了答案。