我想编写一些线程包装器,并且我需要使用void *
作为线程参数,因为我使用的是非C ++ 11线程库。我偶然发现一个问题,并准备了一个最小的工作示例。这是代码:
#include <iostream>
namespace chops {
template <typename T, typename U>
struct is_same {
static const bool value = false;
};
template<typename T>
struct is_same<T, T> {
static const bool value = true;
};
}
template <typename Functor, typename T>
typename Functor::return_type fun_wrapper(T const& arg) {
Functor f;
typename Functor::return_type ret = f(arg);
return ret;
}
struct hello_world {
void operator()(int count) {
while(count--)
std::cout << "hello, world!\n";
}
typedef void return_type;
};
struct is_even {
bool operator()(int x) {
if(!(x % 2))
return true;
else
return false;
}
typedef bool return_type;
};
int main() {
//fun_wrapper<hello_world>(3);
fun_wrapper<is_even>(3);
}
在这里,如果您想在主目录中执行注释掉的行,它将无法编译,因为它想实例化包含如下行的模板
void x = //something
所以我给自己写了一个is_same
类型的特征,并且只想在Functor::return_type
不无效的情况下执行该代码。我想产生效果:
if constexpr(!is_same<Functor::return_type, void>::value) {
typename Functor::return_type res = f(arg);
return ret;
} else {
f(arg);
}
由于我无法使用现代C ++,但仅凭C ++ 17,就好像找不到办法。我不知道如何通过SFINAE之类的东西达到类似的效果。
PS:请注意,这是一个人为的示例,可以进行一些修改,但是在我的实际程序中,如果它不是无效的,则需要创建Functor::return_type
对象。因此,请不要在答案中删除该行。因此,不仅仅是使用return f(arg)
。
答案 0 :(得分:2)
最简单的方法是创建两个重载,一个重载用于block
为input
时,另一个为重载。您要做的就是重新实现//define delegate event so it triggers after inserting new elements (with ajax) too.
$('#newinfo').on('input', 'input[name=firstname]', function(){
console.log($(this).val());
});
//attach the reload_container function to the button for testing purpose
$('#reload').on('click', reload_container);
//This function mimics the result of your ajax request assuming you do something like this. It updates the form with a new form and run the serialize function on it.
function reload_container() {
var ajaxResultMimic = '<form id="selectform">Your name:<br><input type="text" name="firstname" value="updated"><br></form>';
$('#newinfo').html(ajaxResultMimic);
console.log($('#selectform').serialize());
}
(例如,在命名空间<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body>
<button id="reload">reload</button>
<div id="container">
<div id="newinfo">
<form id="selectform">
Your name:<br>
<input type="text" name="firstname"><br>
</form>
</div>
</div>
</body>
中):
$collection->pluck("cat_id")->toArray();
,然后用两个受约束的模板替换单个NotificationCompat.Builder builder = new NotificationCompat.Builder(this, "channel_id_com_app_android")
.setOngoing(false)
.setAutoCancel(true)
.setSmallIcon(R.drawable.notification_icon_2)
.setColor(getResources().getColor(R.color.accent_color))
.setLargeIcon(convertToBitmap(getApplication().getResources().getDrawable(R.mipmap.ic_launcher)))
.setContentTitle(EmojiUtil.decode(name))
.setContentText(EmojiUtil.decode(message))
.setTicker(EmojiUtil.decode(message))
.setStyle(notiStyle)
.setContentIntent(notificationIntent);
builder.setStyle(bigTextStyle);
builder.setPriority(Notification.PRIORITY_HIGH);
builder.build();
NotificationChannel notificationChannel = new NotificationChannel("channel_id_com_app_android", getString(R.string.app_name), NotificationManager.IMPORTANCE_HIGH);
notificationChannel.setLightColor(R.color.accent_color);
notificationChannel.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC);
NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
manager.createNotificationChannel(notificationChannel);
函数模板:
Functor::return_type
wandbox上的实时演示。
答案 1 :(得分:2)
您可以通过在函子的返回类型上部分地专门化类模板来做到这一点(void
是返回类型,并且只有在std::enable_if
的情况下,编译器才会选择专门的版本):< / p>
chops
这可以让您专门针对任何特定类型的行为。如果您宁愿使用template <bool expr, typename T = void>
struct enable_if
{
};
template <typename T>
struct enable_if<true, T>
{
typedef T type;
};
(也许是因为在一个不太人为的示例中,您想稍后再引入其他条件映射到相同的实现),则也可以使用标签分配:
fun_wrapper
答案 2 :(得分:0)
一个相当简单的解决方案,基于“现代C ++”之前使用的两个技巧:
模板专业化
如果没有其他作用,请使用void
的替代品。
示例:
#include <iostream>
template <typename VALUE>
struct Property {
VALUE value;
void set(VALUE value) { this->value = value; }
const VALUE& get() const { return value; }
};
struct Void { };
template <>
struct Property<void>
{
void set() { }
Void get() { return Void(); }
};
std::ostream& operator<<(std::ostream &out, const Void &value)
{
return out;
}
int main()
{
Property<int> propInt;
propInt.set(123);
std::cout << propInt.get() << '\n';
Property<void> propVoid;
std::cout << propVoid.get() << '\n';
return 0;
}
输出:
123
请注意,我使用-std=c++03
进行了编译,以尽可能地使它也可以在非“现代” C ++上运行。
答案 3 :(得分:0)
如果您真的不需要存储函子返回值,而只需要自己返回,则可以在C ++ 03中使用:
#include <iostream>
template <class Functor, class T>
typename Functor::return_type fun_wrapper(T const& arg) {
return Functor()(arg);
}
struct hello_world {
void operator()(int count) {
while(count--)
std::cout << "hello, world!\n";
}
typedef void return_type;
};
int main() {
fun_wrapper<hello_world>(3);
}
如果这是仅适用于您的MCVE的解决方案,则需要void
的显式专业化。