Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.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++ MSVC好友函数声明错误_C++_Templates_Visual C++ - Fatal编程技术网

C++ MSVC好友函数声明错误

C++ MSVC好友函数声明错误,c++,templates,visual-c++,C++,Templates,Visual C++,考虑以下代码: #include <cstddef> template<size_t value> class dummy { }; class my_class { int m_member; // Overload 1 template<size_t value> friend void friend_func(dummy<value>*); // Overload 2 template&

考虑以下代码:

#include <cstddef>

template<size_t value> class dummy { };

class my_class
{
    int m_member;

    // Overload 1
    template<size_t value>
    friend void friend_func(dummy<value>*);

    // Overload 2
    template<size_t value>
    friend void friend_func(int(*)[value]);
};

// Overload 1
template<size_t value>
void friend_func(dummy<value>*)
{
    my_class instance;
    instance.m_member = value;
}

// Overload 2
template<size_t value>
void friend_func(int(*)[value])
{
    my_class instance;
    instance.m_member = value;
}

int main(int argc, char* argv[])
{
    dummy<5> d;
    friend_func(&d);    // call Overload 1
    int arr[5];
    friend_func(&arr);  // call Overload 2 - error in MSVC!
    return 0;
}
对我来说,这看起来像一只虫子。但是,以前有没有人遇到过这样的行为?这真的是一个错误,或者可能是一个特定的错误原因?有什么快速的解决方法吗



编辑:我已经找到了一个合适的解决方法,请参阅。

非常确定这是MSV的一个已知问题。您的具体问题列在中

寻找模板作为朋友。我不知道周围的工作。然而,我认为你可以让班级成为朋友。您可以将其用作解决方法。

这肯定是一个bug:。当
被推断为好友模板函数的数组大小时,会发生此错误。下面是代码的一个简短版本,可以很好地编译。这个示例与您的示例完全相同,只是我指定了数组的大小

class my_class
{
    int m_member;

    template<size_t value>
    friend void friend_func(int(*)[5]);
};

template<size_t value>
void friend_func(int(*)[5])
{
    my_class instance;
    instance.m_member = value;
}

int main()
{
    int arr[5];
    friend_func<5>(&arr);
}

我已经找到了一种解决方法,它既保留了功能,又能防止错误消息。其思想是使用代理函数和代理类来携带指向数组的指针及其大小。以下是解决方案:

#include <cstddef>

// Workaround class for a bug in MSVC.
// https://connect.microsoft.com/VisualStudio/feedback/details/717749
// http://stackoverflow.com/questions/15149607
template<class element_type, size_t count>
class friend_declaration_bug_workaround
{
public:
    typedef element_type(*ptr_type)[count];

private:
    ptr_type m_arr;

public:
    explicit friend_declaration_bug_workaround(ptr_type arr)
        : m_arr(arr)
    {
    }

    ptr_type value() const
    {
        return m_arr;
    }
};

class my_class
{
    int m_member;

    friend void friend_func(int*);

    template<size_t value>
    friend void friend_func_workaround(friend_declaration_bug_workaround<int, value>);
};

template<size_t value>
void friend_func_workaround(friend_declaration_bug_workaround<int, value> workaround)
{
    my_class instance;
    instance.m_member = (*workaround.value())[0];
}

void friend_func(int* arr)
{
    my_class instance;
    instance.m_member = *arr;
}

template<size_t value>
void friend_func(int(*arr)[value])
{
    friend_declaration_bug_workaround<int, value> workaround(arr);
    return friend_func_workaround(workaround);
}

int main(int argc, char* argv[])
{
    int value;
    friend_func(&value);    // call non-templated function
    int arr[5];
    friend_func(&arr);      // call workarounded function
    return 0;
}
#包括
//MSVC中一个bug的解决方案类。
// https://connect.microsoft.com/VisualStudio/feedback/details/717749
// http://stackoverflow.com/questions/15149607
模板
类朋友\u声明\u错误\u解决方法
{
公众:
类型定义元素类型(*ptr类型)[计数];
私人:
ptr_类型m_arr;
公众:
明确的朋友声明错误解决方法(ptr类型arr)
:m_arr(arr)
{
}
ptr_类型值()常量
{
返回m_arr;
}
};
上我的课
{
国际货币联盟成员;
friend void friend_func(int*);
模板
友元无效友元功能解决方案(友元声明解决方案);
};
模板
无效好友功能解决方案(好友声明解决方案)
{
我的_类实例;
instance.m_member=(*workaround.value())[0];
}
无效朋友函数(int*arr)
{
我的_类实例;
instance.m_member=*arr;
}
模板
无效友元函数(int(*arr)[value])
{
朋友声明错误解决方法(arr);
返回friend_func_解决方案(解决方案);
}
int main(int argc,char*argv[])
{
int值;
friend_func(&value);//调用非模板函数
int-arr[5];
friend_func(&arr);//调用变通函数
返回0;
}

叮当声毫无问题地把它吃了,这可能没有什么帮助。对不起,事实并非如此。你提到的这篇文章是为MSVC6写的;我用的是MSVC11。“Templates as Friends”bug很久以前就被修复了,如果不是的话,我的开场白中的第一个重载函数会发出一个错误。谢谢你的链接!你的解决方案有效。但是,使用它时,在没有明确指定(可能不正确)大小的情况下,我丢失了强大小的数组重载。更重要的是,当出现重载时,您发布的第一段代码会产生歧义。我已经设法找到了一个更好的解决方法。只是一个建议,但您可以避免使用
std::vector
std::array
(or)进行所有这些工作。@jessegod当然,但在我的例子中,通用集合类型(适合C++11中基于范围的集合)已经由不同的重载处理,我需要普通的C数组。我明白了,不过,基于C++11范围的for可以处理普通C数组。
template <typename T>
void friend_func(T, int value)
{
    my_class instance;
    instance.m_member = value;
}
#include <cstddef>

// Workaround class for a bug in MSVC.
// https://connect.microsoft.com/VisualStudio/feedback/details/717749
// http://stackoverflow.com/questions/15149607
template<class element_type, size_t count>
class friend_declaration_bug_workaround
{
public:
    typedef element_type(*ptr_type)[count];

private:
    ptr_type m_arr;

public:
    explicit friend_declaration_bug_workaround(ptr_type arr)
        : m_arr(arr)
    {
    }

    ptr_type value() const
    {
        return m_arr;
    }
};

class my_class
{
    int m_member;

    friend void friend_func(int*);

    template<size_t value>
    friend void friend_func_workaround(friend_declaration_bug_workaround<int, value>);
};

template<size_t value>
void friend_func_workaround(friend_declaration_bug_workaround<int, value> workaround)
{
    my_class instance;
    instance.m_member = (*workaround.value())[0];
}

void friend_func(int* arr)
{
    my_class instance;
    instance.m_member = *arr;
}

template<size_t value>
void friend_func(int(*arr)[value])
{
    friend_declaration_bug_workaround<int, value> workaround(arr);
    return friend_func_workaround(workaround);
}

int main(int argc, char* argv[])
{
    int value;
    friend_func(&value);    // call non-templated function
    int arr[5];
    friend_func(&arr);      // call workarounded function
    return 0;
}