#include<iostream>
#include <memory>
#include <thread>
#include <mutex>
using namespace std;
class Linux
{
};
int f1(std::shared_ptr<Linux> spw) // call these only when
{
//do something
return 0;
}
double f2(std::unique_ptr<Linux> upw) // the appropriate
{
//do something
return 0.0;
}
bool f3(Linux* pw) // mutex is locked
{
return 0;
}
std::mutex f1m, f2m, f3m; // mutexes for f1, f2, and f3
using MuxtexGuard = std::lock_guard<std::mutex>;
void lockAndCallF1()
{
MuxtexGuard g(f1m); // lock mutex for f1
auto result = f1(static_cast<int>(0)); // pass 0 as null ptr to f1
cout<< result<<endl;
}
void lockAndCallF2()
{
MuxtexGuard g(f2m); // lock mutex for f2
auto result = f2(static_cast<int>(NULL)); // pass NULL as null ptr to f2
cout<< result<<endl;
}
void lockAndCallF3()
{
MuxtexGuard g(f3m); // lock mutex for f2
auto result = f3(nullptr);// pass nullptr as null ptr to f3
cout<< result<<endl;
} // unlock mutex
int main()
{
lockAndCallF1();
lockAndCallF2();
lockAndCallF3();
return 0;
}
以上程序编译并成功执行但是lockAndCallF1,lockAndCallF2&amp; lockAndCallF3有冗余代码。所以它可以用模板推广。我为冗余代码编写了模板函数lockAndCall
而不是多个定义lockAndCallF1, lockAndCallF2 & lockAndCallF3
。
代码重新计算如下:
#include<iostream>
#include <memory>
#include <thread>
#include <mutex>
using namespace std;
class Linux
{
};
int f1(std::shared_ptr<Linux> spw) // call these only when
{
//do something
return 0;
}
double f2(std::unique_ptr<Linux> upw) // the appropriate
{
//do something
return 0.0;
}
bool f3(Linux* pw) // mutex is locked
{
return 0;
}
std::mutex f1m, f2m, f3m; // mutexes for f1, f2, and f3
using MuxtexGuard = std::lock_guard<std::mutex>;
template<typename FuncType, typename MuxType, typename PtrType>
auto lockAndCall(FuncType func, MuxType& mutex, PtrType ptr) -> decltype(func(ptr))
//decltype(auto) lockAndCall(FuncType func, MuxType& mutex, PtrType ptr)
{
MuxtexGuard g(mutex);
return func(ptr);
}
int main()
{
auto result1 = lockAndCall(f1, f1m, 0); //compilation failed
//do something
auto result2 = lockAndCall(f2, f2m, NULL); //compilation failed
//do something
auto result3 = lockAndCall(f3, f3m, nullptr);
//do something
return 0;
}
编译失败并出现以下错误
$ g++ nullptr.cpp --std=c++11
nullptr.cpp: In function ‘int main()’:
nullptr.cpp:39:49: error: no matching function for call to ‘lockAndCall(double (&)(std::unique_ptr<Linux>), std::mutex&, NULL)’
auto result2 = lockAndCall(f2, f2m, NULL); //compilation failed
^
nullptr.cpp:39:49: note: candidate is:
nullptr.cpp:29:6: note: template<class FuncType, class MuxType, class PtrType> decltype (func(ptr)) lockAndCall(FuncType, MuxType&, PtrType)
auto lockAndCall(FuncType func, MuxType& mutex, PtrType ptr) -> decltype(func(ptr))
^
nullptr.cpp:29:6: note: template argument deduction/substitution failed:
nullptr.cpp: In substitution of ‘template<class FuncType, class MuxType, class PtrType> decltype (func(ptr)) lockAndCall(FuncType, MuxType&, PtrType) [with FuncType = double (*)(std::unique_ptr<Linux>); MuxType = std::mutex; PtrType = long int]’:
nullptr.cpp:39:49: required from here
nullptr.cpp:29:82: error: could not convert ‘ptr’ from ‘long int’ to ‘std::unique_ptr<Linux>’
auto lockAndCall(FuncType func, MuxType& mutex, PtrType ptr) -> decltype(func(ptr))
Question1。为什么lockAndCall调用失败,当参数0或Null f1(std :: shared_ptr spw)和f2(std :: unique_ptr upw)分别和函数调用{{1成功调用0和NULL?}和f1(static_cast<int>(0));
?
Question2 lockAndCall函数扣除后FuncType的类型是什么? FuncType是函数指针的类型或std :: function?
答案 0 :(得分:2)
所以你的问题是声明为:
的函数int f1(std::shared_ptr<Linux> spw);
为什么以下代码编译:
f1(static_cast<int>(0));
但是以下没有:
template<typename FuncType, typename MuxType, typename PtrType>
auto lockAndCall(FuncType func, MuxType& mutex, PtrType ptr) -> decltype(func(ptr))
{
MuxtexGuard g(mutex);
return func(ptr);
}
lockAndCall( f1, f1m, 0);
原因是std::shared_ptr
具有nullptr
的非显式构造函数,值0的整数常量可以隐式转换为nullptr
。当您间接调用f1
时,通过模板函数 - 参数不是值为0的常量表达式,因此无法将其转换为nullptr
。请注意,在运行时该参数中的值无关紧要,这在编译时,在计算表达式的数据类型时解析。
至于NULL
cppreference.com说:
宏NULL是一个实现定义的空指针常量,它可以是求值为零的整数类型的整数常量表达式prvalue或类型为std :: nullptr_t的prvalue(对于C ++ 11)
可能的实施
#define NULL 0
//since C++11
#define NULL nullptr
看起来您的实现已将NULL
定义为文字0,而不是nullptr
要明确解决问题,请{0}或nullptr
或更好的默认构建NULL
或std::shared_ptr
:
std::unique_ptr