我正在处理某个项目,并且在复制功能代码方面存在问题。有没有办法只声明一个函数的单一签名,它将适用于const和非const参数? const和非const函数的实现是相同的。
#include <iostream>
template <class Data>
struct Processor {
int process(const Data &data)
{
return 42;
}
int process(Data &data)
{
return 42;
}
};
int main() {
using data_type = int;
data_type non_const_data = 1;
const data_type const_data = 2;
std::cout << Processor<data_type>().process(non_const_data) << std::endl;
std::cout << Processor<data_type>().process(const_data) << std::endl;
return 0;
}
感谢您的答复
更新
这个例子怎么样?
#include <iostream>
#include <vector>
template <class Container, class Function>
struct Invoker {
const Container& invoke(const Container &container, Function function)
{
for (auto &value : container) function(value);
}
Container& invoke(Container &container, Function function)
{
for (auto &value : container) function(value);
}
};
int main() {
std::vector<int> container {1, 2, 3};
auto fn = [](int val) {
std::cout << val << std::endl;
};
Invoker<decltype(container), decltype(fn)>().invoke(container, fn);
return 0;
}
答案 0 :(得分:8)
如果两个函数的实现相同,则仅提供const
参数函数。在你的情况下,它将同时适用于非const和const对象。
但是,如果要保留这两个函数,可以根据const参数函数实现非const参数函数。它可以帮助您避免重复的代码。
int process(const Data &data)
{
return 42;
}
int process(Data &data)
{
return process(static_cast<const Data&>data);
}
答案 1 :(得分:7)
我建议只声明最具限制性的那个,即期望const参数的那个。如果存在向其发送非const指针/引用的问题,您可以在调用方法之前始终使其成为const。
答案 2 :(得分:6)
是:
int process(const Data &data)
{
return 42;
}
可以使用Data
,Data &
和Data const &
以及任何可转换为Data
的内容进行调用。 const引用可以绑定到非const对象或引用。
答案 3 :(得分:1)
它可能不是您正在寻找的,但在const与非const成员函数的情况下会出现类似的情况。有时,例如在访问函数中,您希望有两个版本,一个可用,如果对象是const,另一个可用,当对象是非const时。
struct MyString {
char & at(int index) {
if (index < size) {
return data[index];
else throw std::range_error("Index out of range");
}
char at(int index) const {
if (index < size) {
return data[index];
else throw std::range_error("Index out of range");
}
};
现在这些功能看起来非常相似,为什么我不能重用一个来实现另一个呢?
答案是你可以,但它需要一些非常小心的转换,首先一般建议是从非const调用const-function。正如您通常可以保证,即使从非const上下文调用const函数也是安全的。对const函数的调用毕竟不会实际改变对象。 (有可变变量的例外情况,或者与我刚才提议的相反。)
解决方案(根据More Effective C++),使用const cast从非const中调用const版本:
const char & at(int index) const {
if (index < size) {
return data[index];
else throw std::range_error("Index out of range");
}
char & at(int index) {
return const_cast<char &>( static_cast<const MyString>(this)->at(index) );
}
这有两个功能。首先,将其转换为const指针,这将允许我们调用at()
的const版本。然后,一旦我们将const-reference返回给元素,就将它转换为可写引用。