代码之家  ›  专栏  ›  技术社区  ›  liori

“f(5)”和“int x;f(x)”调用不同的函数?

c++
  •  2
  • liori  · 技术社区  · 15 年前

    我想写两个不同的函数来处理一个常量值和一个给定类型的变量(即, int )

    下面是示例测试用例:

    int main(void) {
            int x=12;
            F(5); // this should print "constant"
            F(x); // this should print "variable"
    }
    

    我认为这足以定义:

    void F(int v) {  cout << "constant\n"; }
    void F(int& v) { cout << "variable\n"; }
    

    这假设编译器将选择 int& 变量“更专业化”和 int 对于常量是唯一的选择)。然而, G++ 结果是:

    test.cc: In function ‘int main()’:
    test.cc:13: error: call of overloaded ‘F(int&)’ is ambiguous   // for line: F(x);
    test.cc:4: note: candidates are: void F(int)
    test.cc:5: note:                 void F(int&)
    

    G+ 确实选择 F(int) 对于常量,但不知道为变量选择哪个函数。
    有人知道为什么会这样吗?

    背景 我正在用C++中的Prolog类似的统一方法进行实验。能够知道常量和变量之间的差异将有助于我在诸如 functor(x,5) <=> functor(3,5) .

    1 回复  |  直到 15 年前
        1
  •  16
  •   Johannes Schaub - litb    15 年前

    如果您想要区分编译时常量和非编译时常量,那么您就没有机会了。那是不可能的。

    但是,如果要区分非常量变量和常量变量(以及包括的所有内容,如文本),则可以使用常量引用和非常量引用参数重载函数。对于这种情况,C++标准引入了额外的规则,使得这种不明确的情况不含糊。

    void f(int const&); // #1
    void f(int&);       // #2
    

    在这件事上,我们做了以下决定

    int x = 0;
    int const y = x;
    int const z = 1;
    
    f(1); // #1
    f(x); // #2
    f(y); // #1
    f(z); // #1
    

    请注意,它无法区分y和z,即使z的值是编译时常数(称为整型常量表达式或ICE),而y不是。

    你什么 可以 则只接受编译时值。重载函数,使一个是模板,另一个不是模板

    template<int N> void f(); // #1
    void f(int n);            // #2
    

    它的行为如下:

    int x = 0;
    int const y = x;
    int const z = 1;
    
    f<1>(); // #1
    f(1);   // #2
    f<y>(); // error, y not an ICE
    f<z>(); // #1
    f(x);   // #2