Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/159.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++_Guideline Support Library - Fatal编程技术网

C++ 只有在需要时才可以缩小范围吗?

C++ 只有在需要时才可以缩小范围吗?,c++,guideline-support-library,C++,Guideline Support Library,假设我有以下代码,其中bar是在另一个库中定义的: void bar(int x); /* this declaration comes from some included header file */ void foo(long long y) { return bar(y); } 为了使故障可检测,GSL指示我使用GSL::shorrow,如下所示: void bar(int x); /* this declaration comes from some included

假设我有以下代码,其中
bar
是在另一个库中定义的:

void bar(int x);  /* this declaration comes from some included header file */

void foo(long long y)
{
    return bar(y);
}
为了使故障可检测,GSL指示我使用
GSL::shorrow
,如下所示:

void bar(int x);  /* this declaration comes from some included header file */

void foo(long long y)
{
    return bar(narrow<int>(y));
}
所有这些都可以存在于
gsl
名称空间中,我只需将我的函数编写为:

void foo(long long x)
{
    return superint_visit(bar, superint{x});
}

即使我在这里接受了一个答案,我仍然希望听到任何人谁可以使上述发生

对于这个问题,已经发布了非常好的创造性解决方案。但是它们都有依赖于库实现的问题——例如,如果存在条重载,那么客户端代码就无法编译

在我看来,在这种情况下,bar的客户真正想要的是:

“我想使用接受一个特定积分参数的条,如果存在其他重载,则与此无关”

与库无关的非内在直接方法也是最简单的一种方法——一种带有积分参数的细棒包装器。这样,它不依赖于任何库实现细节:

void bar(int x);  /* this declaration comes from some included header file */

template <typename T, typename = std::enable_if_v<std::is_integral_v<T>>>
inline void mybar(T x)
{
     // express directly which bar overload you want to use here 
     bar(narrow<int>(x));  // <- the only place you need to ajudst if bar interface changes, btw. use the overload from bar which you really want
}

void foo(long long y)
{
    return mybar(y);  // use mybar instead of bar within your code
}
void bar(int x);/*此声明来自一些包含的头文件*/
模板
内联无效mybar(T x)
{
//在此处直接表示要使用哪个条重载

bar(窄(x));//您没有
bar
?没问题。只需为
x
获取
decltype
。这可以通过为整个函数获取
decltype
,并编写
模板来恢复参数类型:

template <typename>
struct argType;

template <typename R, typename A>
struct argType<R(A)>
{
    using type = A;
};

void foo(long long y)
{     
    bar(narrow<typename argType<decltype(bar)>::type>(y));
}
模板
结构argType;
模板
结构argType
{
使用类型=A;
};
void foo(长y)
{     
酒吧(窄(y));
}

您可以利用以下事实:重载解析有利于非模板函数与函数模板的完美参数类型匹配:

#include <iostream>

// (A)
void bar(int y) { std::cout << "bar(int)\n"; }
// (B)
//void bar(long long) { std::cout << "bar(long long)\n"; }

// (C)
template <typename T>
void bar(T) = delete;

// (C.SP1)
template<>
void bar<long long>(long long y) { bar(narrow<int>(y)); }

int main() {
    long long a = 12LL;
    bar(a); // bar(int)
            // bar(long long) if `bar(long long)` above is available.
}

获取第一个参数的类型可以使用 具有所有参数的类型,然后可以使用

#包括
空心条(int-y);
void foo(长y)
{
酒吧(窄(y));
}

将bar作为模板如何?这样您就可以调用bar(y)并在bar实现中做出所有与大小相关的决策。对于其客户来说,bar应该能够处理任何整数类型。我认为这是您基本上想要的。不是我的library@stPierence解决方案。但在每次调用bar时都需要编写这些内容的可读性不是很高。也许可以在cust中添加一个级别的间接寻址om功能将更加强大appropriate@StPiere您可以通过typedef或在type
typename argType::type
上使用来缩短它,我想知道std中是否已经有一个很好的解决方案,比如它可能会给出返回值为bar的type。@basheba,当然,那会更好。人们只需要在每次调用什么类型时知道狭义的cast应该是cast。我个人觉得从设计的角度来看这很奇怪,但这不是问题的主题。但还是很好。我的意思是,如果库也有
void bar(char)
,你就不能使用
bar
的类型,当添加
void bar(long-long)
时,代码也会无法编译(允许删除变通方法:)。但是如果
void bar(long-long)
替换
void bar(int)
,它将编译(让变通方法就位)。很好,但这可能会破坏库中的重载解析,具体取决于您何时将模板重载呈现给编译器。@Bathsheba是的,很好。我想您可以为
bar
添加一个公共包装,并将重载解析委派放在定义包装的TU中,为添加的
bar
重载。这与对另一个答案的评论中的限制相同:库中不应存在其他
bar
重载,未来的
bar(long-long)
重载必须取代
bar(int)
one.Nice。这是使用Boost时优雅的结果。+1。
#include <iostream>

// (A)
void bar(int y) { std::cout << "bar(int)\n"; }
// (B)
//void bar(long long) { std::cout << "bar(long long)\n"; }

// (C)
template <typename T>
void bar(T) = delete;

// (C.SP1)
template<>
void bar<long long>(long long y) { bar(narrow<int>(y)); }

int main() {
    long long a = 12LL;
    bar(a); // bar(int)
            // bar(long long) if `bar(long long)` above is available.
}
// foo.h
#pragma once
void foo(long long y);

// foo.cpp
#include "foo.h"
#include "gsl/gsl_narrow"
#include "the_lib/bar.h"

namespace {

template <typename T>
void bar(T) = delete;

template<>
void bar<long long>(long long y) { bar(narrow<int>(y)); }

}  // namespace

void foo(long long y) {
    bar(y);
}
#include <boost/callable_traits/args.hpp>

void bar(int y);

void foo(long long y)
{
  bar(narrow<std::tuple_element<0, boost::callable_traits::args_t<decltype(bar)>>::type>(y));
}