无法定义类中是否存在特定成员变量(静态const引用)

时间:2017-12-13 10:20:12

标签: visual-c++

从MS Visual Studio 2008迁移到MS Visual Studio 2017并使用v140工具集进行编译后,我遇到了定义类中是否存在特定成员变量的问题。 在我的例子中,它不是一个简单的变量,而是一个静态const引用。 它在2008年下运作良好。

以下是我的代码中没有编译的摘录

#include <iostream>
#include <string>


struct ActivityEntry
{
    static const std::string& AutoIncrementName;
};

template< typename Entry >
struct AutoIncrementNameSelect
{    
    template< const std::string* >
    struct TestHasMember;

    template< typename T >
    static int f( TestHasMember< &T::AutoIncrementName >*, void* );

    template< typename T >
    static char f( TestHasMember< &T::AutoIncrementName >*, ... );

    enum { UseAutoIncrement = ( sizeof( f< Entry >( 0, 0 ) ) == sizeof( int ) ) };
};

std::string s("aaa");
//initialize the reference
const std::string & ActivityEntry::AutoIncrementName(s);

int main()
{
    std::cout<<"Use autoinc:"<< AutoIncrementNameSelect<ActivityEntry>::UseAutoIncrement;

    return 0;
}

在我的原始代码中,错误是:“指向引用成员的指针是非法的”,参考:

enum { UseAutoIncrement = ( sizeof( f< Entry >( 0, 0 ) ) == sizeof( int ) ) };

这里错误是

 error: '& ActivityEntry::AutoIncrementName' is not a valid template argument for 'const string* {aka const std::basic_string*}' because it is not the address of a variable

1 个答案:

答案 0 :(得分:1)

您可以将AutoIncrementName修改为std::string对象,而不是参考,以便您可以获取其地址。或者像这样更改两个f()方法:

template< typename T >
static int f( decltype(&T::AutoIncrementName)*, void* );

template< typename T >
static char f( decltype(&T::AutoIncrementName)*, ... );

非类型模板参数有一些限制[temp.arg.nontype]/2

  

2非类型模板参数 template-argument 应为模板参数类型的转换常量表达式(8.20) 。对于引用或指针类型的非类型模板参数,常量表达式的值不应引用(或者对于指针类型,不应是地址):

     

- (2.1)子对象(4.5),

     

- (2.2)临时对象(15.2),

     

- (2.3)字符串文字(5.13.5),

     

- (2.4)typeid表达式(8.2.8)或

的结果      

- (2.5)预先定义的__func__变量(11.4.1)。