Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/152.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 字符串文字和模板函数的多个版本_C++_C++11 - Fatal编程技术网

C++ 字符串文字和模板函数的多个版本

C++ 字符串文字和模板函数的多个版本,c++,c++11,C++,C++11,假设我有一个模板函数: template<typename... Args> void my_log_function(Args&&... args) { // Work, work, work. } 由于字符串文本的类型是const char[n],我相信这将创建大量my_log_函数的实例化(Visual Studio Intellisense似乎建议这样做)。有人认为这是个问题吗?会吗?可以防止吗?是的,这将创建一个不同的类模板实例。它们应该只在通过引

假设我有一个模板函数:

template<typename... Args>
void my_log_function(Args&&... args)
{
    // Work, work, work.
}

由于字符串文本的类型是
const char[n]
,我相信这将创建大量
my_log_函数的实例化(Visual Studio Intellisense似乎建议这样做)。有人认为这是个问题吗?会吗?可以防止吗?

是的,这将创建一个不同的类模板实例。它们应该只在通过引用传递的数组的大小上有所不同,如果它们的数组实际上不再用作数组,那么生成的代码应该是相同的。据我所知,VC++可以折叠相同的代码。但是,如果类型被大量传播,它可能会产生代码膨胀

防止代码膨胀的一种方法是有条件地衰减类型,并转发到另一个执行实际工作的模板。我认为这应该起作用:

template <typename... Args>
void my_real_log_function(Args&&... args) {
    // real implementation goes here
}

template <typename T>
struct decay_array {
    typedef typename std::condition<
        std::is_array<typename std::remove_reference<T>::type>::value,
        typename std::decay<T>::type,
        T>::type type;
};

template <typename... Args>
void my_log_function(Args&&... args) {
    my_real_log_function(std::forward<typename std::decay_array<Args>::type>(args)...);
}
模板
void my_real_log_函数(Args&&…Args){
//真正的实现就在这里
}
模板
结构衰变数组{
typedef typename std::condition<
std::is_array::value,
typename std::Decation::type,
T> ::类型类型;
};
模板
void my_log_函数(Args&&…Args){
my_real_log_函数(std::forward(args)…);
}

仅使用
typename std::decay::type
的原始版本不起作用,因为它会将对非数组的引用转换为不需要的值。

解决方案不是在这样的函数中实现“work,work,work”。将变量参数整理成更规范的形式,并将工作交给非模板


注意膨胀,记住模板系统是为生成内联函数而设计的。

my_log\u函数(+“1”)
Args…
推断为
const char*
(使用一元
+
);类似地,您可以将工作分派到另一个模板,传递衰减的参数(目的是消除/内联最初调用的函数)DyP:Nice trick!但我认为这会让很多人感到困惑…@Potatoswatter:如果某些参数很大和/或不可复制,那么通过我的值传递它们是不可能的。@DyP:是的,你是对的:
std::decation
太激进了,也会删除引用。似乎,只有在传递对数组的引用时,它才会衰减,从而使委托更有趣。@Potatoswatter:同意。我没说它有用。。。我把代码改为当参数是数组时只使用
std::decay
——我想。不过,将数组转换为指针,然后将其委托给另一个函数是一种通用方法。由于这可能是一种常见的需要,因此可能值得研究如何使此操作变得简单。好的……新代码具有不平衡的尖括号和
条件
,而不是
条件
typename std::remove\u reference::value
可能应该是
typename std::remove\u reference::type>:value
平衡支架
template <typename... Args>
void my_real_log_function(Args&&... args) {
    // real implementation goes here
}

template <typename T>
struct decay_array {
    typedef typename std::condition<
        std::is_array<typename std::remove_reference<T>::type>::value,
        typename std::decay<T>::type,
        T>::type type;
};

template <typename... Args>
void my_log_function(Args&&... args) {
    my_real_log_function(std::forward<typename std::decay_array<Args>::type>(args)...);
}