最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

c++ - How to properly define friend function with requires expression - Stack Overflow

programmeradmin1浏览0评论

How can I access private member variable with a friend function that has a requires expression? Is there a way to get the code to compile without removing requires std::is_default_constructible_v<T>?

#include <iostream>
#include <type_traits>

template<typename T>
class Y
{
    static constexpr int data = 10;

    template <typename U>
    friend U pp();
};

template<typename T>
requires std::is_default_constructible_v<T>
T pp()
{
    std::cout << Y<T>::data << '\n';
    return T();
}

int main() {
    pp<int>();
    return 0;
}

Gives error error: 'constexpr const int Y<int>::data' is private within this context

How can I access private member variable with a friend function that has a requires expression? Is there a way to get the code to compile without removing requires std::is_default_constructible_v<T>?

#include <iostream>
#include <type_traits>

template<typename T>
class Y
{
    static constexpr int data = 10;

    template <typename U>
    friend U pp();
};

template<typename T>
requires std::is_default_constructible_v<T>
T pp()
{
    std::cout << Y<T>::data << '\n';
    return T();
}

int main() {
    pp<int>();
    return 0;
}

Gives error error: 'constexpr const int Y<int>::data' is private within this context

Share Improve this question edited Feb 10 at 15:35 jonrsharpe 122k30 gold badges267 silver badges474 bronze badges asked Feb 10 at 15:31 zzazza 1073 silver badges10 bronze badges 2
  • 1 How would you distinguish that pp function from the entirely different template<typename T> requires (!std::is_default_constructible_v<T>) T pp() ? – MSalters Commented Feb 10 at 15:34
  • 4 You need to move definition in-class or repeat the constraint, no other way AFAIK – Yksisarvinen Commented Feb 10 at 15:54
Add a comment  | 

1 Answer 1

Reset to default 5

Note you can have mutiple versions of pp() template with different requriements.

For example this is valid code:

template<typename T>
T pp()
{
    std::cout << "I do not need friendships\n";
    return T();
}

template<typename T>
requires std::is_default_constructible_v<T>
T pp()
{
    std::cout << Y<T>::data << '\n';
    return T();
}

When overload resolution is performed and there are multiple choices with concepts, most specialized version is selected.

So in your code you have declared two versions of pp() like in my example above. One is declared when friendship is defined and other outside a Y class.

As a result Y is friended with a function template which has missing implementation.

So to fix this you must use same concept to funtion tempalte as in function template definition:

template<typename T>
class Y
{
    static constexpr int data = 10;

    template <typename U>
    requires std::is_default_constructible_v<U>
    friend U pp();
};

template<typename T>
requires std::is_default_constructible_v<T>
T pp()
{
    std::cout << Y<T>::data << '\n';
    return T();
}

After that it works as expected: https://godbolt./z/jGEqzhdsW

Moving definition of template inside a class fixes this issue by coincidence, sine at same time you are moving a concept there.

发布评论

评论列表(0)

  1. 暂无评论