概念检查器不编译gcc,因为它'没有链接' [英] concept checker doesn't compile on gcc because it 'has no linkage'
问题描述
我已根据此问题创建了一个概念检查类其目的是确保给定类有一个名为 baseUnitConversionFactor
的静态成员函数。类编译和工作正常与msvc2013,但它不会编译gcc 4.9.2(使用-std = c + + 14)与错误:
I've created a concept checking class based on this question whose purpose is to make sure a given class has a static member function called baseUnitConversionFactor
. The class compiles and works fine with msvc2013, but it wont compile on gcc 4.9.2 (using -std=c++14) with the error:
错误:
不是类型为double(*)的有效模板参数,因此不会显示错误:'{anonymous} :: UnitsTest_conceptChecker_Test :: TestBody():: validUnit :: baseUnitConversionFactor' )',因为
'static double {anonymous} :: UnitsTest_conceptChecker_Test :: TestBody():: validUnit :: baseUnitConversionFactor()'
没有链接
error: ‘{anonymous}::UnitsTest_conceptChecker_Test::TestBody()::validUnit::baseUnitConversionFactor’ is not a valid template argument for type ‘double (*)()’ because ‘static double {anonymous}::UnitsTest_conceptChecker_Test::TestBody()::validUnit::baseUnitConversionFactor()’ has no linkage
static std :: true_type test(tester<& U :: baseUnitConversionFactor> *);
static std::true_type test(tester<&U::baseUnitConversionFactor>*);
我真的不知道这是什么意思,并且更加熟悉在视觉工作室写明模板(显然)更多的允许环境。
I don't really know what that means, and am much more familiar with writing templates in visual studios (obviously) much more permisive enviornment. Can anyone help figure out what I need to do to fix this?
概念检查器类
template <typename T>
struct has_baseUnitConversionFactor
{
template<double(*)()> struct tester;
template<typename U>
static std::true_type test(tester<&U::baseUnitConversionFactor>*);
template<typename U>
static std::false_type test(...);
static const bool value = decltype(test<T>(0))::value;
};
测试我认为会导致错误的 b
TEST_F(UnitsTest, conceptChecker)
{
struct validUnit
{
static inline double baseUnitConversionFactor() { return 0.0; }
typedef void unit_category;
typedef void base_unit_type;
};
EXPECT_TRUE(has_baseUnitConversionFactor<validUnit>::value);
}
推荐答案
在C ++ 11和C ++ 14,指针/引用模板参数必须引用具有链接的实体(在C ++ 03中,它们仅限于具有外部链接的实体)。一个本地类没有链接,它的成员函数也没有。
In C++11 and C++14, pointer/reference template arguments must refer to entities with linkage (in C++03, they were limited to entities with external linkage). A local class has no linkage, and neither do its member functions.
此限制已在C ++ 17中通过 N4268 ,GCC干线声称已实施该文件,但显然不是链接部分。
This restriction has been removed in C++17 by N4268, and GCC trunk claims to have implemented that paper, but apparently not the linkage part.
回避此问题不需要使用& U :: baseUnitConversionFactor
作为模板非类型参数。幸运的是,一个更简单的方法来测试表达式 T :: baseUnitConversionFactor()
是否有效,并且完全返回 double
:
Sidestepping this issue requires not using &U::baseUnitConversionFactor
as a template non-type argument. Happily, a much simpler way to test that the expression T::baseUnitConversionFactor()
is valid and returns exactly double
is:
template <typename T, class=double>
struct has_baseUnitConversionFactor : std::false_type { };
template <typename T>
struct has_baseUnitConversionFactor<T, decltype(T::baseUnitConversionFactor())>
: std::true_type { };
这取决于表达式SFINAE(但是,原来也是这样),所以我不是确保它能在MSVC 2013上正常工作。
This does depend on expression SFINAE (but then, so does the original), so I'm not sure if it will work on MSVC 2013.
有关更一般的检查,您可以查看 std :: experimental :: is_detected_convertible
。该cppreference页面有一个引用实现。
For a more general check, you may want to look at std::experimental::is_detected_convertible
. That cppreference page has a reference implementation.
这篇关于概念检查器不编译gcc,因为它'没有链接'的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!