避免为未使用的抽象可选函数参数保留名称

Avoid Name Reservation for Unused Abstract Optional Function Arguments

提问人:kaisong 提问时间:10/29/2023 最后编辑:kaisong 更新时间:10/29/2023 访问量:62

问:

我有一个求解器类模板,可以使用可选的 ostream 调用其求解例程。

在所述类模板的专用化下,从不使用 ostream。

问题

为什么我不能从下面的最小示例中删除字符序列“fdsa”,并让它实现与我从代码中类似的期望相同的行为,即:foo

  1. 我在一个地方定义。foo
  2. 我不需要为 . 的第二个参数添加标签。foo
  3. 我可以用一个或两个参数调用。foo

最小示例

#include <iostream>
#include <cassert>

template<typename T>
class OptionalWrapper{
    T* p;
public:
    const bool is_empty;
    OptionalWrapper(void):is_empty(true),p(NULL){}
    OptionalWrapper(T& r):is_empty(false),p(&r){}
    T& operator()(void){ assert(!is_empty); return *p; }
    T const& operator()(void)const{ assert(!is_empty); return *p; }
};

template<typename Tfloat>
struct Solver{
    // ... lot of other code
    void compute(Tfloat&x, OptionalWrapper<std::ostream> o=OptionalWrapper<std::ostream>() ){
        if(!o.is_empty) o()<<"solver<float>::compute("<<x<<");\n";
    }
};

template<>
struct Solver<double>{
    // ... lot of uncorrelated specialized code
    void compute(double&x, OptionalWrapper<std::ostream> fdsa=OptionalWrapper<std::ostream>() ){
        std::cout << "solver<double>::compute("<<x<<");\n";
    }
};

int main() {
    //
    float xf = 1;
    double xd = 2;
    //
    Solver<float> sf;
    Solver<double> sd;
    //
    sf.compute(xf,std::cout);
    sf.compute(xf);
    //
    sd.compute(xd,std::cout);
    sd.compute(xd);
}

它是否与 3/5 的规则有关,我不能随便用 ?OptionalWrapper<std::ostream> fdsa=OptionalWrapper<std::ostream>()OptionalWrapper<std::ostream> =OptionalWrapper<std::ostream>()

(备注:在类专用化体之外定义函数将导致 GCC 接受,并且上述不带“fdsa”的代码将被 CLANG、MVSC、ICX 和 ZIG 接受。因此,也许从这个问题中确实没有太多的见解。我很抱歉现在才知道。

我的期望

我可以使用与

int foo(int x, int=0){
    return 2*x;
}
int main() {
    foo(1);
    foo(2,3);
    return 0;
}

并且不需要为 ,第二个参数提供标签。基本上,我认为对于编译器来说,第二个参数的类型甚至无关紧要,因为它无论如何都不会被函数体处理。y

c++ 可选参数 三法则

评论

0赞 Darius 10/29/2023
如果它从未使用过,为什么它出现在函数参数中? 如果我说,就不会编译.int foo(int x, int){ return 2*x; }foo(1);
0赞 wohlstad 10/29/2023
如果未使用参数名称,则可以从方法中省略参数名称,但参数仍然存在,并且在调用方法时必须传递一些参数。
0赞 kaisong 10/29/2023
@Darius。好点子!因此,ostream 位于函数参数中,因为用户可以将其写入其中。想想一个用于在 Tfloat=SensitivityAnalysisNumber 中进行调试的应用程序,并使用 double 发布,但无论如何,用户可能已经或可能没有附加 ostream 来查看 Tfloat=SensitivityAnalysis 时的收敛行为。
0赞 kaisong 10/29/2023
@wohlstad。您能澄清一下如何从方法定义中省略参数名称吗?因为这正是我的问题。
1赞 Jarod42 10/29/2023
您应该已提供(失败并显示)尝试的错误消息。

答:

2赞 Jarod42 10/29/2023 #1

OptionalWrapper<std::ostream>=OptionalWrapper<std::ostream>()有解析问题,您需要额外的空间:

OptionalWrapper<std::ostream> =OptionalWrapper<std::ostream>().

演示

else 被视为greater_than,(类似于关闭双模板的旧问题)。>=>>

评论

0赞 kaisong 10/29/2023
哦,我注意到了。因此,为什么我在最小的例子中写下了关于“......lof 其他代码”。因为,是的,当你在类体之外定义函数时,它就会起作用。但我无法理解它。为什么我必须在课外写它。这只会让它的可读性降低。
1赞 Jarod42 10/29/2023
我在类体中定义函数...您的问题是“解析令牌”,额外的空格可以解决问题。
0赞 BoP 10/29/2023
@kaisong - 问题出在声明中,它不适合声明,因为它看起来像一个比较。>=
0赞 kaisong 10/29/2023
哦,我从 Tfloat 的计算中删除了它。我很抱歉!我的错。o