Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/160.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++_C++11_Templates_Reference_Auto_C++14_C++17_C++03 - Fatal编程技术网

C++ 在C+中组织涉及有限范围的常量引用和模板的代码的好方法+;

C++ 在C+中组织涉及有限范围的常量引用和模板的代码的好方法+;,c++,c++11,templates,reference,auto,c++14,c++17,c++03,C++,C++11,Templates,Reference,Auto,C++14,C++17,C++03,因此,我有以下代码: if (some_boolean_statement) { const auto& ref = getRef<TYPE_A>(); //getRef returns TYPE_A doStuff(ref); } else { const auto& ref = getRef<TYPE_B>(); //getRef returns TYPE_B doStuff(ref); } if(一些布尔语句) {

因此,我有以下代码:

if (some_boolean_statement)
{
    const auto& ref = getRef<TYPE_A>(); //getRef returns TYPE_A
    doStuff(ref);
}
else
{
    const auto& ref = getRef<TYPE_B>(); //getRef returns TYPE_B
    doStuff(ref);
}
if(一些布尔语句)
{
const auto&ref=getRef();//getRef返回类型A
多斯塔夫(参考);
}
其他的
{
const auto&ref=getRef();//getRef返回类型
多斯塔夫(参考);
}
因此,我想获得一个常量引用
ref
,它取决于
某个布尔语句
true
false
类型a
类型B
。 之后,不管怎样,我都将调用一个重载函数
doStuff()
,该函数可以接受这两种类型作为输入

注:

  • getRef()
    getRef()
    是在不同的数据上操作的,它们几乎是不相关的
  • 某些布尔语句是运行时的
现在,我不喜欢我必须写
doStuff(ref)。但是由于
ref
的范围有限,我看不到一个明确的方法来实现它


我错过了一些非常简单的东西吗?有什么建议吗?

由于在运行时对某个布尔语句进行了计算,因此无法避免代码中的
if-else
部分

如果
语句的每个分支中必须包含的最少代码量是一条语句。最好是编写其他函数或函数模板,以尽量减少两个分支中的代码量

你可以用

if (some_boolean_statement)
{
   doStuff<TYPE_A>();
}
else
{
   doStuff<TYPE_B>();
}
if(一些布尔语句)
{
doStuff();
}
其他的
{
doStuff();
}
在哪里

template <typename T> void doStuff()
{
   doStuff(getRef<T>());
}
模板void doStuff()
{
doStuff(getRef());
}

我看不出你还能做得比这更好。此外,如果这是您的代码中最大的问题,那么您的代码的状态很好。

将控制流和运行时转换为编译时调度器

这是疯狂的复杂,和适度复杂的

在中,您可以获得:

pick( some_boolean_statement,
  &getRef<TYPE_A>,
  &getRef<TYPE_B>
)([&](auto* getRef){
  const auto& ref = getRef();
  doStuff(ref);
});

可以编写类似于交换机的dispatcher类,该类将条件值映射到目标类型,并接受只执行一次的操作,因此用法类似于:

 Switch<Action, bool, Case<true, TYPE_A>, Case<false, TYPE_B>>(some_boolean_statement);

Switch

第一次调用的类型与第二次调用的类型之间是否存在任何关系?@raket1111
getRef
是一个模板函数,它将溢出
类型a
类型B
的对象。根据不同的情况,它将执行非常不同的不相关的操作。@Jarod42不幸的是,没有。那么这段代码有什么不好的地方呢?如果两个分支都在不同的类型上运行并执行不同的任务,那么我看不出有什么问题。键入
doStuff
两次似乎不是构建某些模板(调用这些模板可能需要大约相同的键入量)的充分理由。删除
ref
变量:)
if(cond){doStuff(getRef());}else{doStuff(getRef());}
 Switch<Action, bool, Case<true, TYPE_A>, Case<false, TYPE_B>>(some_boolean_statement);
#include <iostream>
#include <cstdlib>

template<auto cond, typename x_Target> struct
Case;

template<template<typename T> class x_Action, typename x_Cond, typename... x_Case>
class DispatchImpl;

template<template<typename T> class x_Action, typename x_Cond, x_Cond this_cond, typename x_Target, typename... x_Case>
class DispatchImpl<x_Action, x_Cond, Case<this_cond, x_Target>, x_Case...>
{
    public: static void Dispatch(x_Cond cond)
    {
        if(this_cond == cond)
        {
            x_Action<x_Target>::Invoke();
        }
        else
        {
            DispatchImpl<x_Action, x_Cond, x_Case...>::Dispatch(cond);
        }
    }
};

template<template<typename T> class x_Action, typename x_Cond>
class DispatchImpl<x_Action, x_Cond>
{
    public: static void Dispatch(x_Cond) {}
};

template<template<typename T> class x_Action, typename x_Cond, typename... x_Case>
void Switch(x_Cond cond)
{
    DispatchImpl<x_Action, x_Cond, x_Case...>::Dispatch(cond);
}

//
template<typename T> auto getRef(void) { return T{}; }
void doStuff(int) { ::std::cout << "int" << ::std::endl; }
void doStuff(float) { ::std::cout << "float" << ::std::endl; }

template<typename x_Target> struct
Action
{
    static void Invoke(void)
    {
        doStuff(getRef<x_Target>());
    } 
};

int main()
{
   auto cond{false};
   Switch<Action, bool, Case<true, int>, Case<false, float>>(cond);
}