在下面的代码中,在set()a 上调用一个成员函数model,它是一个空指针。这将是未定义的行为。然而,成员函数的参数是另一个函数调用的结果,该函数调用检查是否为model空指针并在这种情况下抛出异常。是否保证estimate()总是在访问之前被调用model,还是仍然是未定义行为(UB)?
#include <iostream>
#include <memory>
#include <vector>
struct Model
{
void set(int x)
{
v.resize(x);
}
std::vector<double> v;
};
int estimate(std::shared_ptr<Model> m)
{
return m ? 3 : throw std::runtime_error("Model is not set");
}
int main()
{
try
{
std::shared_ptr<Model> model; // null pointer here
model->set(estimate(model));
}
catch (const std::runtime_error& e)
{
std::cout << e.what();
}
return 0;
}
Run Code Online (Sandbox Code Playgroud) 我一直在努力理解C++选择模板的方式.即,请考虑以下代码示例:
template <typename R>
class Curious
{
public:
template <typename T, typename std::enable_if<std::is_const<T>::value, int>::type = 33>
void test1() {}
template <typename T, typename std::enable_if<!std::is_const<T>::value, int>::type = 33>
void test1() {}
template <typename T, typename = typename std::enable_if<std::is_const<T>::value>::type>
void test2() {}
template <typename T, typename = typename std::enable_if<!std::is_const<T>::value>::type>
void test2() {}
template <typename std::enable_if<std::is_const<R>::value>::type * = nullptr>
void test3() {}
template <typename std::enable_if<!std::is_const<R>::value>::type * = nullptr>
void test3() {}
// works
template <typename T = void>
typename std::enable_if<std::is_const<R>::value, T>::type test4() {} …Run Code Online (Sandbox Code Playgroud) 我注意到函数模板中静态变量初始化的一个奇怪的行为.请考虑以下示例:
MyFile * createFile()
{
std::cout << "createFile" << std::endl;
return nullptr;
}
template <typename T>
void test(const T& t)
//void test(T t)
{
static MyFile *f = createFile();
}
void main()
{
test("one");
//test("two");
test("three");
}
Run Code Online (Sandbox Code Playgroud)
只要f在test是静态的,我预计createFile将只调用一次.但是,它被调用两次.
花了一些时间来解决这个问题,我注意到从参数中删除const引用来test修复它.另一个有趣的事情是传递给函数的字符串的长度也会影响初始化:当参数的长度相等时,静态变量只初始化一次,否则会发生新的初始化.
有人可以解释一下吗?除了上面提到的解决方案/解决方案之外,我们非常欢迎.
我一直在尝试使用集成到 Visual Studio 2019 的 LLVM 编译器构建OpenMP示例程序。
从这里下载LLVM编译器(版本10.0,win64),C:\Program Files\LLVM\bin添加到PATH环境变量中。LLVM 编译器工具链扩展是从Visual Studio Marketplace安装的。
它成功构建了一个 hello world 程序,但是当我尝试使用 OpenMP 时,链接器失败并出现以下错误:
1>clang version 10.0.0
1>Target: x86_64-pc-windows-msvc
1>Thread model: posix
1>InstalledDir: C:\Program Files\LLVM\bin
1> (in-process)
1> "C:\\Program Files\\LLVM\\bin\\clang-cl.exe" -cc1 -triple x86_64-pc-windows-msvc19.26.28805 -emit-obj -mrelax-all -mincremental-linker-compatible -disable-free -disable-llvm-verifier -discard-value-names -main-file-name llvmtest.cpp -mrelocation-model pic -pic-level 2 -mthread-model posix -mframe-pointer=none -relaxed-aliasing -fmath-errno -fno-rounding-math -masm-verbose -mconstructor-aliases -munwind-tables -target-cpu x86-64 -mllvm -x86-asm-syntax=intel -D_DEBUG -D_MT -D_DLL --dependent-lib=msvcrtd --dependent-lib=oldnames -stack-protector 2 -fcxx-exceptions -fexceptions -fexternc-nounwind …Run Code Online (Sandbox Code Playgroud) C++14 添加了变量模板,它定义了相关变量组。在标准库中,变量模板用于访问每个类型特征的值成员:
template<class T>
inline constexpr bool is_arithmetic_v = is_arithmetic<T>::value;
Run Code Online (Sandbox Code Playgroud)
C++17 添加了内联变量以更好地支持仅头文件库,这些库可以包含在同一应用程序内的多个源文件中(不同的翻译单元中允许相同的内联变量定义)。但就变量模板而言,无论如何它们都可以在程序中具有多个定义。那么,如果变量模板已经免于 ODR,还有什么理由将它们声明为内联呢?
只要很多人都关注constexpr差异inline constexpr,这是另一个有趣的问题,我就想忽略constexpr这次讨论的目的。
template <typename T>
bool myVar = sizeof(T) > 1;
Run Code Online (Sandbox Code Playgroud)
它与以下内容有何不同:
template <typename T>
inline bool myVar = sizeof(T) > 1;
Run Code Online (Sandbox Code Playgroud) 我需要在QTreeView中实现通过drag-n-drop移动的行,并显示行之间的拖放指示符.我想知道是否有一种方法来覆盖指示器绘图,因此它仅显示行之间的所有层次结构(不是项目周围的矩形),该行必须与整行(而不是一列)一样宽).
我需要一些关于 thread_local 对象销毁的澄清。第一个问题是什么时候发生?C++ 参考资料如下:
对象的存储在线程开始时分配,并在线程结束时释放。每个线程都有自己的对象实例。只有声明为 thread_local 的对象才具有此存储持续时间。
不幸的是,线程何时结束并不总是显而易见的。让我们考虑以下示例:
#include <iostream>
#include <vector>
#include <algorithm>
#include <execution>
#include <mutex>
struct MyClass
{
MyClass()
{
std::scoped_lock<std::mutex> lck(mtx);
std::cout << "ctor" << std::endl << std::flush;
}
~MyClass()
{
std::scoped_lock<std::mutex> lck(mtx);
std::cout << "dtor" << std::endl << std::flush;
}
static std::mutex mtx;
};
std::mutex MyClass::mtx;
int main(int argc, char* argv[])
{
std::vector<int> v(1000000, 3);
std::transform(std::execution::par, v.begin(), v.end(), v.begin(), [](int x)
{
thread_local MyClass myclass;
return x * x;
});
std::cout << "done" << std::endl; …Run Code Online (Sandbox Code Playgroud) 我正在为 Android 开发一个基于 Qt 的应用程序。如果应用程序因打开文件而启动,我需要将其传递给 Qt 应用程序实例。我创建了一个自定义 Java 活动来实现此行为:
public class MyActivity extends org.qtproject.qt5.android.bindings.QtActivity
{
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
Intent i = getIntent();
String act = i.getAction();
if (act != null) && act.compareTo(Intent.ACTION_VIEW) == 0)
{
int fd = -1;
try
{
fd = getContentResolver().openFileDescriptor(i.getData(), "r").detachFd();
}
catch (IOException e)
{
Log.e("MyActivity::onCreate", "Exception caught: " + e.getMessage());
}
boolean ok = openFd(fd);
}
} // onCreate
private static native boolean openFd(int fd);
} // MyActivity
Run Code Online (Sandbox Code Playgroud)
在 C++ …
考虑以下示例:
#include <iostream>
struct X
{
X() = default;
X(const X&) = default;
X(X&&) = default;
X& operator = (const X&) = default;
X& operator = (X&&) = default;
};
int main()
{
static_assert(std::is_nothrow_move_assignable_v<X>);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
移动赋值运算符似乎是隐式的noexcept,因为静态断言通过了。
然而,超出范围的定义会使断言失败:
#include <iostream>
struct X
{
X() = default;
X(const X&) = default;
X(X&&) = default;
X& operator = (const X&) = default;
X& operator = (X&&); //= default;
};
X& X::operator=(X&&) = default;
int main()
{
static_assert(std::is_nothrow_move_assignable_v<X>);
return …Run Code Online (Sandbox Code Playgroud) 该文档指出std::make_shared<T>通常分配用于存储T在对比一次和智能指针的控制块std::shared_pointer<T>(new T),它执行两个分配.这是否意味着它更有效率,因此std::make_shared如果可能的话应该总是使用它?
关于Qt等价的相同问题 - QSharedPointer.根据文档,QSharedPointer内部和对象分配在一个单独的内存分配中,这可以帮助减少长时间运行的应用程序中的内存碎片.这是否QSharedPointer<T>::create()是首选?
class MyClass {};
QSharedPointer<MyClass> ptr1 = QSharedPointer<MyClass>::create(); // better
QSharedPointer<MyClass> ptr2(new MyClass); // worse
Run Code Online (Sandbox Code Playgroud)