我正在尝试将检测添加到我的产品中广泛使用的模板类中。我目前正在VS 2019 (16.10.4)
使用/std:c++17
. 的新功能std::source_location
对于我有兴趣解决的任务来说是一个很好的补充。虽然std::source_location
并且std::experimental::source_location
在我的编译器上不可用,但我根据这个答案构建了我自己的。我的目标是在特殊的构建和运行测试中更改类构造函数/成员。对类本身的更改不会改变其用法,因此其余代码保持不变。
这一切都可以编译并且效果很好 - 主要是。除了,我遇到了几乎超出使用目的的复制省略std::source_location
。我希望我source_location
成为定义调用者变量的位置,而不是创建实际对象的位置。
gcc -std=c++20
这个问题也可以在有和没有的情况下得到证明-fno-elide-constructors
。请参阅我的最小可重现Godbolt 示例的简化版本。
我的课:
class MyClass
{
private:
int m_a = 0;
std::source_location m_location;
public:
MyClass(std::source_location location = std::source_location::current())
: m_location(location)
{
}
MyClass(const MyClass &other, std::source_location location = std::source_location::current())
: m_a(other.m_a)
, m_location(location)
{
}
MyClass(MyClass &&other, std::source_location location = std::source_location::current())
: m_a(other.m_a)
, m_location(location)
{
}
};
用法:
MyClass getCopy1()
{
MyClass ret;
return ret;
}
MyClass getCopy2()
{
return MyClass();
}
int main()
{
MyClass o1;
MyClass o2(o1);
MyClass o3(getCopy1());
MyClass o4(getCopy2());
std::cout << "o1: " << o1.getLocationInfo() << std::endl;
std::cout << "o2: " << o2.getLocationInfo() << std::endl;
std::cout << "o3: " << o3.getLocationInfo() << std::endl;
std::cout << "o4: " << o4.getLocationInfo() << std::endl;
return 0;
}
实际输出:
o1: /app/example.cpp(56:13) int main()
o2: /app/example.cpp(57:18) int main()
o3: /app/example.cpp(46:12) MyClass getCopy1()
o4: /app/example.cpp(51:20) MyClass getCopy2()
预期输出:
o1: /app/example.cpp(56:13) int main()
o2: /app/example.cpp(57:18) int main()
o3: /app/example.cpp(58:26) int main()
o4: /app/example.cpp(59:26) int main()
解决方法 1(显式参数):
MyClass o3(getCopy1(), std::source_location::current());
MyClass o4(getCopy2(), std::source_location::current());
解决方法 2 ( std::move
):
MyClass o3(std::move(getCopy1()));
MyClass o4(std::move(getCopy2()));
虽然上述任何解决方法都给了我想要的结果,但它们是不切实际的。这些将需要我更改使用代码的几个实例,并且会达到使用类似std::source_location
. 对MyClass.h/cpp
不破坏其使用的任何更改或对编译器标志的任何更改都是公平的游戏。我打算有一个不会在生产中使用的单独的检测构建。我的产品目前基于VS 2019 (16.10.4)
./std:c++17