我试图找到一种方法来减少一些语法“噪音”而不诉诸宏。对于以下代码:
struct base { base() = delete; };
struct tag1 final : private base
{
static constexpr const char* name = "tag1";
};
template <typename T> std::string name() { return T::name; }
// ...
int main()
{
const std::string name1(name<tag1>());
return 0;
}
最好摆脱一些static constexpr const char*
(更不用说另一种)语法,因为重复tag2
,tag3
等等会很烦人。另外,真正有趣的唯一部分是tag1
,其余部分是“噪音”。直接解决方案 使用宏:
#define MAKE_TAG(tag_name) struct tag_name final : private base { \
static constexpr const char* name = #tag_name; }
MAKE_TAG(tag2);
// ...
const std::string name2(name<tag2>());
基于宏的MAKE_TAG(tag2);
语法删除了tag2
的所有“噪音”,非常突出。宏的一个额外好处是tag_name
可以很容易地变成一个字符串文字,以防止复制粘贴错误。
“明显”可能的解决方案可能是通过name
as a template argument
template<const char* name> base { ... };
struct tag3 final : private base<"tag3"> {};
但那是not supported by C++。从下面的answer开始,巧妙的解决方法是使用可变参数模板:
template<char... S> struct base { base() = delete;
static std::string name() { return{ S... }; } };
struct tag4 final : base<'t', 'a', 'g', '4'> { };
template <typename T> std::string name() { return T::name(); }
这确实减少了很多噪音,但需要写't', 'a', 'g', '4'
而不是"tag4"
。运行时解决方案相当简洁
struct base {
const std::string name;
base(const std::string& name) : name(name) {} };
struct tag5 final : base { tag5() : base("tag5") {} };
template <typename T> std::string name() { return T().name; }
但这并不完全令人满意,因为tag5
现在可以实例化,理想情况下没有意义。此外,现在需要写三次tag5
,这不是DRY。
有没有办法进一步简化(即减少打字)上面的代码? ......没有使用宏?
答案 0 :(得分:4)
如果您愿意单独输入字符,我们可以执行以下操作:
**taskkill /PID number that represent the PID**
这样称呼:
template<char... S>
struct base {
base() = delete;
static std::string name(){
return {S...};
}
};
struct tag1 final : private base<'t','a','g','1'>
{using base::name;};
struct tag2 final : private base<'t','a','g','2'>
{using base::name;};
我必须在派生类中添加std::cout << tag1::name() << std::endl;
std::cout << tag2::name() << std::endl;
,因为您正在使用私有继承。如果继承变为using base::name
或protected
,则您不需要。
基础中public
函数的要点是创建一个我们可以从中构造字符串的字符数组。我们使用variadic parameter pack expansion来创建数组。
答案 1 :(得分:3)
如果您只想获取该类型的名称,您可以这样做(至少对于GCC):
// ==UserScript==
// @name test
// @include https://www.younow.com/*
// @version 1
// @grant none
// @require https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js
// ==/UserScript==
var observer = null;
initObserver();
function initObserver()
{
observer = new MutationObserver(onMutation);
observer.observe(document,
{
childList: true, // report added/removed nodes
subtree: true, // observe any descendant elements
});
}
$(window).on('hashchange', function(e)
{
initObserver();
});
intervalMutation = setInterval(onMutation.bind(null, null), 1000);
function locationObserver()
{
var oldLocation = location.href;
setInterval(function() {
if(location.href != oldLocation) {
onMutation(null);
oldLocation = location.href
}
}, 1000); // check every second
}
locationObserver();
function onMutation(mutations)
{
// Check if this class exits:
if($('.trending-now').length ||
$('.ynicon ynicon-chat').length ||
$('.trending_title').length ||
$('.trending-tags-list').length)
{
// Disconnect the observer:
observer.disconnect();
// Clear the interval :
clearInterval(intervalMutation);
// Call your code:
pageReady();
}
}
function pageReady()
{
// your code here:
alert('start');
}
唯一的缺点是在返回的字符串末尾有一个尾随']'。
如果您愿意放弃 template <typename T> constexpr const char *get_type_name()
{
const char *name = __PRETTY_FUNCTION__;
while (*name++ != '[');
for (auto skip_space = 3 ; skip_space ; --skip_space)
{
while (*name++ != ' ');
}
return name;
}
// ...
auto name1 = get_type_name<int>();
auto name2 = get_type_name<tag1>();
要求,那么您可以轻松删除那个讨厌的最后一个字符。
请注意,这是非标准且不可移植的。