Tre*_*key 23 c c++ parameters parameter-passing c++11
如果你要查看这段代码,
int x = 0;
function(x);
std::cout << x << '\n';
Run Code Online (Sandbox Code Playgroud)
您将无法通过任何语法方式验证参数x是通过引用传递还是通过值传递.您可以肯定的唯一方法是查看函数声明或函数定义.
这是一个简单的例子,我认为这可能是一个问题:
std::string Lowercase(std::string str); //<- this is hidden away in code; probably in a different file.
int main(){
std::string str = "HELLO";
Lowercase(str);
std::cout << str << '\n'; //<- Bug! we expected to output "hello". The problem is not very easy to spot, especially when a function name sounds as though it will change the passed in value.
}
Run Code Online (Sandbox Code Playgroud)
为了避免必须在函数调用和函数声明(或在某些情况下,文档)之间跳转以理解函数行为,有没有办法在函数调用的语法中显式地记录参数是期望改变(即参考参数)或发送副本(即通过值传递)?
我意识到还有一个选择传递const&,它具有类似于传递值的概念,因为传入的变量在函数调用之后不会更改其值.
我确信语言中有各种各样的情况可能会增加理解参数传递的复杂性 - 但我很好奇,有没有办法以我想要的方式解决这个问题?
我注意到有些人写了两个类似的功能.其中一个采用值参数,另一个采用指针.这允许调用这样的函数:
Lowercase(str); //we assume the value will not change
Lowercase(&str); //we assume the value will change
Run Code Online (Sandbox Code Playgroud)
但是这个解决方案还有很多其他问题,我不想失去参考的好处.另外,我们仍在对行为做出假设.
Die*_*ühl 24
有些人坚持认为传递可变对象的正确方法是使用指针.也就是说,你会通过
Lowercase(&str);
Run Code Online (Sandbox Code Playgroud)
...... Lowercase()
显然,实现了一个指针.这种方法可能适合您的需求.
但是,我想提一下,这不是我要做的!相反,我赞成的方法是使用适当的名称.例如,
inplace_lowercase(str);
Run Code Online (Sandbox Code Playgroud)
几乎说了它将要做什么.显然,inplace_lowercase()
实际上是一个算法,并且可以合理地称之为具有一点魔力
inplace_lowercase(str.begin() + 1, str.end());
Run Code Online (Sandbox Code Playgroud)
同样.
以下是我不喜欢通过指针传递参数和/或为什么我不相信参数如何传递的明确指示的几个原因:
T const*
.我不确定我完全理解你的要求,但也许这是你可以使用的东西:
template<typename T>
void foo( T ) { static_assert( sizeof(T)==0, "foo() requires a std::ref" ); }
void foo( std::reference_wrapper<int> t )
{
// modify i here via t.get() or other means of std::reference_wrapper
}
int main()
{
int i = 42;
// foo( i ); // does not compile, static_assert fires
foo( std::ref( i ) ); // explicit std::ref visible on the caller's side
}
Run Code Online (Sandbox Code Playgroud)