从MS Visual Studio 2008迁移到MS Visual Studio 2017并使用V140 Toolset进行编译后,我在定义类中是否存在特定成员变量的问题。就我而言,这不是一个简单的变量,而是一个静态常量引用。它在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
您可以将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 a 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)。