对 constexpr 函数的嵌套调用

nested calls to constexpr functions

以下(通用)情况:

我试图在 class 中调用另一个 constexpr 成员函数,但我得到 'this' is not a constant expression 的错误。我现在的问题是(因为我是 constexpr 习语的新手),是否不允许这样的用例。否则,我该如何解决?

#include <iostream>

class cc
{
public:
    cc()=default;
    ~cc()=default;

    // public method to call th eprivate constexpr functions
    template<int varbase>
    constexpr void doSomething()
    {
        static_assert(varbase>0, "varbase has to be greater zero");
        // nested call to constexpr functions
        char x=testM2<testM1<varbase>()>();
    }

private:

    template<int var1>
    constexpr int testM1()
    {
     int temp=var1;
     return (++temp);
    }

    template<int var2>
    constexpr char testM2()
    {
        int temp=var2;
        if (temp==2)
            return 'A';
        else
            return 'B';
    }
};

int main()
{
    cc obj;
    obj.doSomething<1>();
    return 0;
}

Run the above example

问题是 cc 的每个实例都会有自己的 doSomething()testM1()testM2() 版本。
为了解决这个问题,编译器将在所有函数前面应用 this,以识别您要引用的 cc 的哪个实例。

this 不是常量表达式。它在运行时进行评估。
这就是您收到错误的原因:'this' is not a constant expression

要解决此问题,请将您的 constexpr 函数移到 class 之外,或者将这些函数标记为 static

这是您的代码的工作修订版,它也适用于 C++11。

#include <iostream>

template<int var1>
constexpr int testM1() // move these functions outside, if they use no data of class cc
{
    return int{var1 + 1};
}

template<int var2>
constexpr char testM2()
{
    return (var2 == 2) ? 'A' : 'B';
}

class cc
{
public:
    cc()=default;
    ~cc()=default;

    // public method to call the private constexpr functions
    template<int varbase>
    static constexpr void doSomething() 
    {
        /* if you want to keep it inside class, mark it `static` 
           so that the compiler understands that it will be shared by all instances. */
        static_assert(varbase>0, "varbase has to be greater zero");
        // nested call to constexpr functions
        constexpr char x = testM2<testM1<varbase>()>(); // preferably x should be `constexpr`
    }
};

int main()
{
    cc obj;
    obj.doSomething<2>();
    return 0;
}

所以constexpr并不代表"this function can only be called at compile time"。意思是"this function may be called both at compile and run time".

    char x=testM2<testM1<varbase>()>();

如果在 运行 时调用,this 的值不是编译时常量。所以 constexpr 方法调用的结果不是编译时值,所以它的结果不能用作模板参数。

如果您没有使用 this(您似乎没有使用),则将 testM2 等标记为 static 可以解决您的问题。如果您使用 this 则没有简单的解决方法;没办法说"this function will only be called at compile time"。如果可能的话,任何解决方法都将取决于您使用 this 和 return 值所做的详细信息。写一个添加了这些细节的新问题。