特定类型的强制功能模板/功能过载

时间:2013-03-01 23:36:43

标签: c++ templates overloading

我有一个功能

foo(int, int, int, int/long long/_int64/double/long double/char *, int ONLY IF previous char * - otherwise unneeded)

问题是,由于需要字符串副本,char *实现与值类型不同。是的,这是旧代码的接口,所以我不能使用std :: string:/

目前,我已经将它作为模板,以及char *的函数重载,带有额外的参数。但是,其他类型的所有操作在char *上也是有效的,因此如果调用者忘记了最后一个参数,则该函数会默认匹配模板,从而产生错误的逻辑。

有什么方法可以强制在函数模板中使用重载/使用默认参数/允许特定类型的不同签名(额外参数),而不是静默匹配较小的签名?

更多: 暂时无法访问C ++ 11,但我很乐意看到使用它来帮助推动采用的建议。 没有提升,但与上面相同

我也试过

return_type foo(int,int,int,typename std::enable_if<!std::is_pointer<T>::value, T>::type & value2update)

没有任何运气。然后它声称用双&amp;参数无法匹配。

2 个答案:

答案 0 :(得分:2)

您可以让链接器帮助您。在标题中声明(但不定义)函数模板和char*重载:

template<typename T>
foo(int, int, int, T);
foo(int, int, int, char*, int);

在实现文件(.cpp / .cc)中,实现:

template<typename T>
foo(int, int, int, T) { ... }

foo(int, int, int, char*, int) { ... }

显式实例化您要接受的类型的版本:

template<>
foo(int, int, int, int);
template<>
foo(int, int, int, long long);
// etc.

如果我理解正确,ScottLamb会在评论中提出这样的建议。部首:

foo(int, int, int, int);
foo(int, int, int, long long);
...
foo(int, int, int, char*, int);

实施文件(.cpp / .cc):

namespace {
    template<typename T>
    foo_tmpl(int, int, int, T) { ... }
}

foo(int, int, int, int) { foo_tmpl(...); }
foo(int, int, int, long long) { foo_tmpl(...); }
....
foo(int, int, int, char*, int) { ... }

从使用标题的人的角度来看这是最好的(他们可以立即看到哪些重载可用),但在实现方面需要稍微多做些工作。

答案 1 :(得分:1)

使用帮助程序类string_ref为您捆绑两个参数:

class string_ref {
  const char *str;
  std::size_t len;
public:
  string_ref(std::string const& s)
    : str(s.c_str()), len(s.size()) {}

  string_ref(const char *c, std::size_t len)
    : str(c), len(len) {}

  const char * c_str() const { return str; }
  std::size_t size() const { return len; }
};

然后

foo(int, int, int, int/long long/_int64/double/long double/const char*, [int])

添加

foo(int, int, int, string_ref)
{
   foo(int, int, int, c_str(), size());
}

string_ref可以从const char*int创建,没有任何开销,可以轻松提取两者以进一步传递给C函数。

(命名string_refnot random。)