据我所知,一个非常常见的情况是这样的
template<int i> class Class
{
public:
static constexpr int I = i;
static constexpr int J = constexprFunction(i);
// further Class implementation
};
Run Code Online (Sandbox Code Playgroud)
几乎同样普遍的我看到错误(事实上我的大部分问题是因为我忘记了,并且不知道,正确的问题是什么)如果成员使用的话会忘记附加的定义:
template<int i> constexpr int Class<i>::I;
template<int i> constexpr int Class<i>::J;
Run Code Online (Sandbox Code Playgroud)
现在我读了cppreference:Definitions和ODR以及cppreference:静态成员,声明这是C++ 17不推荐使用的.这对我来说似乎很棒,因为它避免了很多错误.但是还有其他问题出现了:
1)这改变了其他原因,而不是使附加定义无用吗?(另见本问题的最后一段)
2)在cppreference的最后一个例子中:静态成员似乎也适用于const static成员 - 但规则只声明了constexpr成员.是否适用于const static会员?
3)所有的例子,我发现用一个简单的定义一样Class::I-做这一切还保持了形势Class:J与constexpr功能?
简要说明在C++ 17和C++ 17之前最佳实践是什么.总而言之,这对我来说似乎是一个非常棘手的变化,因为它会产生很多代码,这些代码之前需要"格式化不需要诊断"才能获得良好的代码(据我所知......).因此,会产生代码,对于较早的(前17版)编译器仍然是"不需要的非诊断" - 但只要不需要使用odr,这些就不会抱怨.
编辑:更正了Aaron McDaid建议的文字.
我知道有很多类似的问题,但不知何故有不同的问题.这是关于以下情况:
#include <iostream>
#include <array>
template<typename T> class MyClass
{
public:
static constexpr std::array<T,4> ARRAY {{4, 3, 1, 5}};
};
int main()
{
constexpr std::array<int, 4> my_array(MyClass<int>::ARRAY); // works fine -> can use the ARRAY to initialize constexpr std::array
constexpr int VALUE = 5*MyClass<int>::ARRAY[0]; // works also fine
int value;
value = my_array[0]; // can assign from constexpr
value = MyClass<int>::ARRAY[0]; // undefined reference to `MyClass<int>::ARRAY
std::cout << VALUE << std::endl;
std::cout << value << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
据我所知 …
这个问题是this one的后续问题。
这是关于nvcc编译器将static constexpr设备代码中的类变量识别为未定义的,如果该变量是 odr 使用的。但是,我找不到原因,为什么它不起作用。
错误信息是:
error: identifier "Tester<int> ::ONE" is undefined in device code
Run Code Online (Sandbox Code Playgroud)
编译与
nvcc -std=c++11 -ccbin=/usr/bin/g++-4.9 -arch=sm_30 main.cu
Run Code Online (Sandbox Code Playgroud)
该nvcc编译器版本release 8.0, V8.0.26。
一个最小的例子(上一个问题中的 MWE 的缩短版本,专注于这个特定问题)由
#include <iostream>
#include <cstdlib>
#ifdef __CUDACC__
#define HD __host__ __device__
#else
#define HD
#endif
HD void doSomething(const int& var ) {};
template<typename T> class Tester
{
public:
static constexpr int ONE = 1;
HD void test()
{
doSomething( ONE );
}
}; …Run Code Online (Sandbox Code Playgroud)